1 #include "moab/Core.hpp"
2 #include "moab/Range.hpp"
3
4 using namespace moab;
5
6 #include <string.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <assert.h>
10 #include <map>
11 #include <vector>
12 #include <algorithm>
13 #include <sstream>
14
15 #include "TestUtil.hpp"
16
17 std::string poly_example = TestDir + "/io/poly8-10.vtk";
18 std::string polyhedra_example = TestDir + "/io/polyhedra.vtk";
19
20 #define DECLARE_TEST(A) \
21 bool test_ ## A(); \
22 int A ## _reg_var = register_test( &test_ ## A, #A );
23
24 typedef bool (*test_ptr)();
25 struct test_data { test_ptr test; const char* name; bool result; };
26 size_t num_tests = 0;
27 test_data *test_array = 0;
register_test(test_ptr test,const char * name)28 int register_test( test_ptr test, const char* name )
29 {
30 test_data* new_test_array = (test_data*)realloc( test_array, sizeof(test_data)*(num_tests+1) );
31 if (!new_test_array) {
32 fprintf(stderr, "VtkTest.cpp::regeister_test(): reallocation of test array failed\n");
33 free(test_array);
34 test_array = NULL;
35 num_tests = 0;
36 return -1;
37 }
38 else
39 test_array = new_test_array;
40 test_array[num_tests].test = test;
41 test_array[num_tests].name = name;
42 test_array[num_tests].result = true;
43 ++num_tests;
44 return 0;
45 }
46
47 DECLARE_TEST(edge2)
DECLARE_TEST(edge3)48 DECLARE_TEST(edge3)
49 DECLARE_TEST(tri3)
50 DECLARE_TEST(tri6)
51 DECLARE_TEST(quad4)
52 DECLARE_TEST(quad8)
53 DECLARE_TEST(quad9)
54 DECLARE_TEST(polygon)
55 DECLARE_TEST(polygon_mix)
56 DECLARE_TEST(polyhedra)
57 DECLARE_TEST(tet4)
58 DECLARE_TEST(tet10)
59 DECLARE_TEST(hex8)
60 DECLARE_TEST(hex20)
61 DECLARE_TEST(hex27)
62 DECLARE_TEST(wedge)
63 DECLARE_TEST(wedge15)
64 DECLARE_TEST(pyramid)
65 DECLARE_TEST(pyramid13)
66
67 DECLARE_TEST(structured_points_2d)
68 DECLARE_TEST(free_nodes)
69 //DECLARE_TEST(free_nodes_and_triangle)
70
71 DECLARE_TEST(structured_grid_2d)
72 DECLARE_TEST(rectilinear_grid_2d)
73 DECLARE_TEST(structured_points_3d)
74 DECLARE_TEST(structured_grid_3d)
75 DECLARE_TEST(rectilinear_grid_3d)
76
77 DECLARE_TEST(scalar_attrib_1_bit)
78 DECLARE_TEST(scalar_attrib_1_uchar)
79 DECLARE_TEST(scalar_attrib_1_char)
80 DECLARE_TEST(scalar_attrib_1_ushort)
81 DECLARE_TEST(scalar_attrib_1_short)
82 DECLARE_TEST(scalar_attrib_1_uint)
83 DECLARE_TEST(scalar_attrib_1_int)
84 DECLARE_TEST(scalar_attrib_1_ulong)
85 DECLARE_TEST(scalar_attrib_1_long)
86 DECLARE_TEST(scalar_attrib_1_float)
87 DECLARE_TEST(scalar_attrib_1_double)
88
89 DECLARE_TEST(scalar_attrib_4_bit)
90 DECLARE_TEST(scalar_attrib_4_uchar)
91 DECLARE_TEST(scalar_attrib_4_char)
92 DECLARE_TEST(scalar_attrib_4_ushort)
93 DECLARE_TEST(scalar_attrib_4_short)
94 DECLARE_TEST(scalar_attrib_4_uint)
95 DECLARE_TEST(scalar_attrib_4_int)
96 DECLARE_TEST(scalar_attrib_4_ulong)
97 DECLARE_TEST(scalar_attrib_4_long)
98 DECLARE_TEST(scalar_attrib_4_float)
99 DECLARE_TEST(scalar_attrib_4_double)
100
101 DECLARE_TEST(vector_attrib_bit)
102 DECLARE_TEST(vector_attrib_uchar)
103 DECLARE_TEST(vector_attrib_char)
104 DECLARE_TEST(vector_attrib_ushort)
105 DECLARE_TEST(vector_attrib_short)
106 DECLARE_TEST(vector_attrib_uint)
107 DECLARE_TEST(vector_attrib_int)
108 DECLARE_TEST(vector_attrib_ulong)
109 DECLARE_TEST(vector_attrib_long)
110 DECLARE_TEST(vector_attrib_float)
111 DECLARE_TEST(vector_attrib_double)
112
113 DECLARE_TEST(tensor_attrib_uchar)
114 DECLARE_TEST(tensor_attrib_char)
115 DECLARE_TEST(tensor_attrib_ushort)
116 DECLARE_TEST(tensor_attrib_short)
117 DECLARE_TEST(tensor_attrib_uint)
118 DECLARE_TEST(tensor_attrib_int)
119 DECLARE_TEST(tensor_attrib_ulong)
120 DECLARE_TEST(tensor_attrib_long)
121 DECLARE_TEST(tensor_attrib_float)
122 DECLARE_TEST(tensor_attrib_double)
123
124 DECLARE_TEST(subset)
125 DECLARE_TEST(write_free_nodes)
126
127 DECLARE_TEST(unstructured_field)
128
129 int main( int argc, char* argv[] )
130 {
131 int *test_indices = (int*)malloc(sizeof(int) * num_tests);
132 int test_count;
133 // if no arguments, do all tests
134 if (argc == 1) {
135 for (unsigned i = 0; i < num_tests; ++i)
136 test_indices[i] = i;
137 test_count = num_tests;
138 }
139 // otherwise run only specified tests
140 else {
141 test_count = 0;
142 for (int i = 1; i < argc; ++i)
143 for (unsigned j = 0; j < num_tests; ++j)
144 if (!strcmp( test_array[j].name, argv[i]))
145 test_indices[test_count++] = j;
146 }
147
148 int fail_count = 0;
149 for (int i = 0; i < test_count; ++i) {
150 test_data& test = test_array[test_indices[i]];
151 printf("Testing %s...\n", test.name );
152 if (!(test.result = test.test()))
153 ++fail_count;
154 }
155
156 printf("\n\n");
157 if (fail_count) {
158 printf("FAILED TESTS:\n");
159 for (int i = 0; i < test_count; ++i) {
160 test_data& test = test_array[test_indices[i]];
161 if (!test.result)
162 printf("\t%s\n", test.name);
163 }
164 }
165
166 if (test_count == 0)
167 printf("0 VTK tests run\n");
168 else if (fail_count == 0)
169 printf("%d tests passed\n", test_count );
170 else
171 printf("%d of %d tests failed\n", fail_count, test_count);
172 printf("\n");
173
174 free(test_indices);
175 free(test_array);
176
177 return fail_count;
178 }
179 // CHECK is defined in TestUtil now
180 #undef CHECK
181 #define CHECK(A) if (is_error((A))) return do_error( #A, __LINE__ )
do_error(const char * string,int line)182 static bool do_error( const char* string, int line )
183 {
184 fprintf(stderr, "Check failed at line %d: %s\n", line, string );
185 return false;
186 }
is_error(bool b)187 static inline bool is_error( bool b )
188 { return !b; }
189
190 //static bool do_error( ErrorCode err, int line )
191 //{
192 // Core tmp_core;
193 // fprintf(stderr, "API failed at line %d: %s (%d)\n",
194 // line, tmp_core.get_error_string(err).c_str(), (int)err );
195 // return false;
196 //}
is_error(ErrorCode b)197 static inline bool is_error( ErrorCode b )
198 { return MB_SUCCESS != b; }
199
200 bool read_file( Interface* iface, const char* file );
201 bool write_and_read( Interface* iface1, Interface* iface2 );
202
203 bool test_read_write_element( const double* coords, unsigned num_coords,
204 const int* vtk_conn, const int* moab_conn,
205 unsigned num_conn,
206 unsigned num_elem, unsigned vtk_type,
207 EntityType moab_type );
208
test_edge2()209 bool test_edge2()
210 {
211 const double coords[] =
212 { 0, 0, 0,
213 1, 0, 0,
214 1, 1, 0,
215 0, 1, 0,
216 0, 0, 1 };
217 const int conn[] =
218 { 0, 1,
219 1, 2,
220 2, 3,
221 3, 4,
222 0, 4 };
223
224 return test_read_write_element( coords, 5, conn, conn, 10, 5, 3, MBEDGE );
225 }
226
test_edge3()227 bool test_edge3()
228 {
229 const double coords[] =
230 { -1, -1, 2,
231 1, -1, 2,
232 1, 1, 2,
233 -1, 1, 2,
234 0.000, -0.707, 2,
235 0.707, 0.000, 2,
236 0.000, 0.707, 2,
237 -0.707, 0.000, 2 };
238 const int conn[] =
239 { 0, 1, 4,
240 1, 2, 5,
241 2, 3, 6,
242 3, 0, 7 };
243
244 return test_read_write_element( coords, 8, conn, conn, 12, 4, 21, MBEDGE );
245 }
246
247
test_tri3()248 bool test_tri3()
249 {
250 const double coords[] =
251 { 0, 0, 0,
252 5, 0, 0,
253 0, 5, 0,
254 -5, 0, 0,
255 0, -5, 0 };
256 const int conn[] =
257 { 0, 1, 2,
258 0, 2, 3,
259 0, 3, 4,
260 0, 4, 1 };
261
262 return test_read_write_element( coords, 5, conn, conn, 12, 4, 5, MBTRI );
263 }
264
test_tri6()265 bool test_tri6()
266 {
267 const double coords[] =
268 { 0, 2, 0,
269 0, 0, 2,
270 0, -2, 0,
271 0, 0, -2,
272 0, 1, 1,
273 0, -1, 1,
274 0, -1, -1,
275 0, 1, -1,
276 0, 0, 0 };
277 const int conn[] =
278 { 0, 1, 3, 4, 5, 8,
279 1, 2, 3, 6, 7, 8 };
280
281 return test_read_write_element( coords, 9, conn, conn, 12, 2, 22, MBTRI );
282 }
283
284 const double grid_3x3[] =
285 { 0, 0, 0,
286 1, 0, 0,
287 2, 0, 0,
288 3, 0, 0,
289 0, 1, 0,
290 1, 1, 0,
291 2, 1, 0,
292 3, 1, 0,
293 0, 2, 0,
294 1, 2, 0,
295 2, 2, 0,
296 3, 2, 0,
297 0, 3, 0,
298 1, 3, 0,
299 2, 3, 0,
300 3, 3, 0 };
301
302 const int quad_structured_conn[] =
303 { 0, 1, 5, 4,
304 1, 2, 6, 5,
305 2, 3, 7, 6,
306 4, 5, 9, 8,
307 5, 6, 10, 9,
308 6, 7, 11, 10,
309 8, 9, 13, 12,
310 9, 10, 14, 13,
311 10, 11, 15, 14 };
312
test_quad4()313 bool test_quad4()
314 {
315 // test read as quads
316 bool rval1 = test_read_write_element( grid_3x3, 16, quad_structured_conn, quad_structured_conn, 36, 9, 9, MBQUAD );
317
318 // test read as pixels
319 const int conn2[] =
320 { 0, 1, 4, 5,
321 1, 2, 5, 6,
322 2, 3, 6, 7,
323 4, 5, 8, 9,
324 5, 6, 9, 10,
325 6, 7, 10, 11,
326 8, 9, 12, 13,
327 9, 10, 13, 14,
328 10, 11, 14, 15 };
329 bool rval2 = test_read_write_element( grid_3x3, 16, conn2, quad_structured_conn, 36, 9, 8, MBQUAD );
330
331 return rval1 && rval2;
332 }
333
test_quad8()334 bool test_quad8()
335 {
336 const double coords[] =
337 { 0, 0, 0,
338 0, 2, 0,
339 0, 4, 0,
340 0, 0, 4,
341 0, 2, 4,
342 0, 4, 4,
343 4, 0, 0,
344 4, 2, 0,
345 4, 4, 0,
346 2, 0, 0,
347 2, 4, 0,
348 0, 0, 2,
349 0, 4, 2
350 };
351 const int conn[] =
352 { 0, 2, 5, 3, 1, 12, 4, 11,
353 2, 0, 6, 8, 1, 9, 7, 10 };
354
355 return test_read_write_element( coords, 13, conn, conn, 16, 2, 23, MBQUAD );
356 }
357
test_quad9()358 bool test_quad9()
359 {
360 const double coords[] =
361 { 0, 0, 0,
362 0, 2, 0,
363 0, 4, 0,
364 0, 0, 4,
365 0, 2, 4,
366 0, 4, 4,
367 4, 0, 0,
368 4, 2, 0,
369 4, 4, 0,
370 2, 0, 0,
371 2, 2, 0,
372 2, 4, 0,
373 0, 0, 2,
374 0, 2, 2,
375 0, 4, 2
376 };
377 const int conn[] =
378 { 0, 2, 5, 3, 1, 14, 4, 12, 12,
379 2, 0, 6, 8, 1, 9, 7, 11, 10 };
380
381 return test_read_write_element( coords, 15, conn, conn, 18, 2, 28, MBQUAD );
382 }
383
test_polygon()384 bool test_polygon()
385 {
386 const double coords[] =
387 { 0, 0, 0,
388 0, 2, 0,
389 0, 4, 0,
390 0, 0, 4,
391 0, 2, 4,
392 0, 4, 4,
393 4, 0, 0,
394 4, 2, 0,
395 4, 4, 0,
396 2, 0, 0,
397 2, 4, 0,
398 0, 0, 2,
399 0, 4, 2
400 };
401 const int conn[] =
402 { 0, 1, 2, 12, 5, 4, 3, 11,
403 2, 1, 0, 9, 6, 7, 8, 10 };
404
405 return test_read_write_element( coords, 13, conn, conn, 16, 2, 7, MBPOLYGON );
406 }
407
test_polygon_mix()408 bool test_polygon_mix()
409 {
410 // just read the polygon file with mixed sequences
411 Core moab;
412 Interface& mb = moab;
413
414 ErrorCode rval = mb.load_file(poly_example.c_str());
415 if (MB_SUCCESS!=rval)
416 return false;
417
418 return true;
419
420 }
test_polyhedra()421 bool test_polyhedra()
422 {
423 // just read the polyhedra file
424 Core moab;
425 Interface& mb = moab;
426
427 ErrorCode rval = mb.load_file(polyhedra_example.c_str());
428 if (MB_SUCCESS!=rval)
429 return false;
430 Range polyhedras;
431 rval = mb.get_entities_by_type(0, MBPOLYHEDRON, polyhedras);
432 if (MB_SUCCESS!=rval)
433 return false;
434
435 if (10!=polyhedras.size())
436 return false;
437 return true;
438
439 }
test_tet4()440 bool test_tet4()
441 {
442 const double coords[] =
443 { 1, -1, 0,
444 1, 1, 0,
445 -1, 1, 0,
446 -1, -1, 0,
447 0, 0, -1,
448 0, 0, 1 };
449 const int conn[] =
450 { 0, 1, 3, 5,
451 1, 2, 3, 5,
452 0, 1, 4, 3,
453 1, 2, 4, 3 };
454
455 return test_read_write_element( coords, 6, conn, conn, 16, 4, 10, MBTET );
456 }
457
test_tet10()458 bool test_tet10()
459 {
460 const double coords[] =
461 { 4, 0, 0,
462 0, 2, 0,
463 0,-2, 0,
464 0, 0,-2,
465 0, 0, 2,
466 0, 1, 1,
467 2, 0, 1,
468 0,-1, 1,
469 0, 0, 0,
470 2, 1, 0,
471 2,-1, 0,
472 2, 0,-1,
473 0,-1,-1,
474 0, 1,-1 };
475 const int conn[] =
476 { 0, 1, 2, 4, 9, 8, 10, 6, 5, 7,
477 2, 1, 0, 3, 8, 9, 10, 12, 13, 11 };
478
479 return test_read_write_element( coords, 14, conn, conn, 20, 2, 24, MBTET );
480 }
481
482 const double grid_2x2x2[] =
483 { 0, 0, 0,
484 1, 0, 0,
485 2, 0, 0,
486 0, 1, 0,
487 1, 1, 0,
488 2, 1, 0,
489 0, 2, 0,
490 1, 2, 0,
491 2, 2, 0,
492 0, 0, 1,
493 1, 0, 1,
494 2, 0, 1,
495 0, 1, 1,
496 1, 1, 1,
497 2, 1, 1,
498 0, 2, 1,
499 1, 2, 1,
500 2, 2, 1,
501 0, 0, 2,
502 1, 0, 2,
503 2, 0, 2,
504 0, 1, 2,
505 1, 1, 2,
506 2, 1, 2,
507 0, 2, 2,
508 1, 2, 2,
509 2, 2, 2 };
510
511 const int hex_structured_conn[] =
512 { 0, 1, 4, 3, 9,10,13,12,
513 1, 2, 5, 4,10,11,14,13,
514 3, 4, 7, 6,12,13,16,15,
515 4, 5, 8, 7,13,14,17,16,
516 9,10,13,12,18,19,22,21,
517 10,11,14,13,19,20,23,22,
518 12,13,16,15,21,22,25,24,
519 13,14,17,16,22,23,26,25 };
520
test_hex8()521 bool test_hex8()
522 {
523 // check vtk hexes
524 bool rval1 = test_read_write_element( grid_2x2x2, 27, hex_structured_conn, hex_structured_conn, 64, 8, 12, MBHEX );
525 CHECK(rval1);
526
527 const int conn2[] =
528 { 0, 1, 3, 4, 9,10,12,13,
529 1, 2, 4, 5,10,11,13,14,
530 3, 4, 6, 7,12,13,15,16,
531 4, 5, 7, 8,13,14,16,17,
532 9,10,12,13,18,19,21,22,
533 10,11,13,14,19,20,22,23,
534 12,13,15,16,21,22,24,25,
535 13,14,16,17,22,23,25,26 };
536
537 // check with vtk voxels
538 bool rval2 = test_read_write_element( grid_2x2x2, 27, conn2, hex_structured_conn, 64, 8, 11, MBHEX );
539 CHECK(rval2);
540
541 return true;
542 }
543
test_hex20()544 bool test_hex20()
545 {
546 const int vtk_conn[] =
547 { 0, 2, 8, 6,
548 18, 20, 26, 24,
549 1, 5, 7, 3,
550 19, 23, 25, 21,
551 9, 11, 17, 15 };
552 const int exo_conn[] =
553 { 0, 2, 8, 6,
554 18, 20, 26, 24,
555 1, 5, 7, 3,
556 9, 11, 17, 15,
557 19, 23, 25, 21 };
558
559 return test_read_write_element( grid_2x2x2, 27, vtk_conn, exo_conn, 20, 1, 25, MBHEX );
560 }
561
test_hex27()562 bool test_hex27()
563 {
564 const int vtk_conn[] =
565 { 0, 2, 8, 6,
566 18, 20, 26, 24,
567 1, 5, 7, 3,
568 19, 23, 25, 21,
569 9, 11, 17, 15,
570 10, 16, 14, 12,
571 4, 22, 13 };
572 const int moab_conn[] =
573 { 0, 2, 8, 6,
574 18, 20, 26, 24,
575 1, 5, 7, 3,
576 9, 11, 17, 15,
577 19, 23, 25, 21,
578 14, 16, 12, 10,
579 4, 22, 13 };
580
581 return test_read_write_element( grid_2x2x2, 27, vtk_conn, moab_conn, 27, 1, 29, MBHEX );
582 }
583
test_wedge()584 bool test_wedge()
585 {
586 const double coords[] =
587 { 1, 0, 0,
588 1, 1, 0,
589 0, 1, 0,
590 0, 0, 0,
591 1, 0, 1,
592 1, 1, 1,
593 0, 1, 1,
594 0, 0, 1 };
595 const int exo_conn[] =
596 { 0, 1, 3, 4, 5, 7,
597 1, 2, 3, 5, 6, 7 };
598 const int vtk_conn[] =
599 { 0, 3, 1, 4, 7, 5,
600 1, 3, 2, 5, 7, 6 };
601 return test_read_write_element( coords, 8, vtk_conn, exo_conn, 12, 2, 13, MBPRISM );
602 }
603
test_wedge15()604 bool test_wedge15()
605 {
606 const double coords[] =
607 { 2, 0, 0,
608 2, 2, 0,
609 0, 2, 0,
610 0, 0, 0,
611 2, 0, 2,
612 2, 2, 2,
613 0, 2, 2,
614 0, 0, 2,
615 2, 1, 0,
616 1, 2, 0,
617 0, 1, 0,
618 1, 0, 0,
619 1, 1, 0,
620 2, 1, 2,
621 1, 2, 2,
622 0, 1, 2,
623 1, 0, 2,
624 1, 1, 2,
625 2, 0, 1,
626 2, 2, 1,
627 0, 2, 1,
628 0, 0, 1 };
629 const int exo_conn[] =
630 { 0, 1, 3, 4, 5, 7, 8, 12, 11, 18, 19, 21, 13, 17, 16,
631 1, 2, 3, 5, 6, 7, 9, 10, 12, 19, 20, 21, 14, 15, 17 };
632 const int vtk_conn[] =
633 { 0, 3, 1, 4, 7, 5, 11, 12, 8, 16, 17, 13, 18, 21, 19,
634 1, 3, 2, 5, 7, 6, 12, 10, 9, 17, 15, 14, 19, 21, 20 };
635 return test_read_write_element( coords, 22, vtk_conn, exo_conn, 30, 2, 26, MBPRISM );
636 }
637
test_pyramid()638 bool test_pyramid()
639 {
640 const double coords[] =
641 { 1, -1, 0,
642 1, 1, 0,
643 -1, 1, 0,
644 -1, -1, 0,
645 0, 0, -1,
646 0, 0, 1 };
647 const int conn[] =
648 { 0, 1, 2, 3, 5,
649 3, 2, 1, 0, 4 };
650
651 return test_read_write_element( coords, 6, conn, conn, 10, 2, 14, MBPYRAMID );
652 }
653
test_pyramid13()654 bool test_pyramid13()
655 {
656 const double coords[] =
657 { 2, -2, 0,
658 2, 2, 0,
659 -2, 2, 0,
660 -2, -2, 0,
661 0, 0, -2,
662 0, 0, 2,
663 2, 0, 0,
664 0, 2, 0,
665 -2, 0, 0,
666 0, -2, 0,
667 1, -1, -1,
668 1, 1, -1,
669 -1, 1, -1,
670 -1, -1, -1,
671 1, -1, 1,
672 1, 1, 1,
673 -1, 1, 1,
674 -1, -1, 1 };
675 const int conn[] =
676 { 0, 1, 2, 3, 5, 6, 7, 8, 9, 14, 15, 16, 17,
677 3, 2, 1, 0, 4, 8, 7, 6, 9, 13, 12, 11, 10 };
678
679 return test_read_write_element( coords, 18, conn, conn, 26, 2, 27, MBPYRAMID );
680 }
681
682 bool test_structured_2d( const char* file );
683 bool test_structured_3d( const char* file );
684
test_structured_points_2d()685 bool test_structured_points_2d()
686 {
687 const char file[] =
688 "# vtk DataFile Version 3.0\n"
689 "MOAB Version 1.00\n"
690 "ASCII\n"
691 "DATASET STRUCTURED_POINTS\n"
692 "DIMENSIONS 4 4 1\n"
693 "ORIGIN 0 0 0\n"
694 "SPACING 1 1 1\n";
695 bool rval1 = test_structured_2d( file );
696
697 // test again w/ old 1.0 ASPECT_RATIO keyword
698 const char file2[] =
699 "# vtk DataFile Version 3.0\n"
700 "MOAB Version 1.00\n"
701 "ASCII\n"
702 "DATASET STRUCTURED_POINTS\n"
703 "DIMENSIONS 4 4 1\n"
704 "ORIGIN 0 0 0\n"
705 "ASPECT_RATIO 1 1 1\n";
706 bool rval2 = test_structured_2d( file2 );
707
708 return rval1 && rval2;
709 }
test_free_vertices(const char * file)710 bool test_free_vertices (const char * file)
711 {
712 // read VTK file
713 Core instance;
714 bool bval = read_file( &instance, file ); CHECK(bval);
715 return true;
716 }
717
test_free_nodes()718 bool test_free_nodes()
719 {
720 const char file1[] =
721 "# vtk DataFile Version 3.0\n"
722 "MOAB Version 1.00\n"
723 "ASCII\n"
724 "DATASET UNSTRUCTURED_GRID\n"
725 "POINTS 2 double\n"
726 "10.0 0 0\n"
727 "-10.0 0 0\n"
728 "CELLS 2 4\n"
729 "1 0\n"
730 "1 1\n"
731 "CELL_TYPES 2\n"
732 "1\n"
733 "1\n" ;
734
735 bool rval1 = test_free_vertices(file1);
736
737 const char file2[] =
738 "# vtk DataFile Version 3.0\n"
739 "MOAB Version 1.00\n"
740 "ASCII\n"
741 "DATASET UNSTRUCTURED_GRID\n"
742 "POINTS 5 double\n"
743 "10.0 0 0\n"
744 "-10.0 0 0\n"
745 "-5 2. 2.\n"
746 "-5 2. 0.\n"
747 "-5 4. 2.\n"
748 "CELLS 3 8\n"
749 "1 0\n"
750 "1 1\n"
751 "3 2 3 4\n"
752 "CELL_TYPES 3\n"
753 "1\n"
754 "1\n"
755 "5\n";
756
757 bool rval2 = test_free_vertices(file2);
758 return rval1 && rval2;
759
760 }
test_structured_grid_2d()761 bool test_structured_grid_2d()
762 {
763 char file[4096] =
764 "# vtk DataFile Version 3.0\n"
765 "MOAB Version 1.00\n"
766 "ASCII\n"
767 "DATASET STRUCTURED_GRID\n"
768 "DIMENSIONS 4 4 1\n"
769 "POINTS 16 double\n";
770 int len = strlen(file);
771 for (unsigned i = 0; i < 16; ++i)
772 len += sprintf(file+len, "%f %f %f\n", grid_3x3[3*i], grid_3x3[3*i+1], grid_3x3[3*i+2]);
773
774 return test_structured_2d( file );
775 }
776
test_rectilinear_grid_2d()777 bool test_rectilinear_grid_2d()
778 {
779 const char file[] =
780 "# vtk DataFile Version 3.0\n"
781 "MOAB Version 1.00\n"
782 "ASCII\n"
783 "DATASET RECTILINEAR_GRID\n"
784 "DIMENSIONS 4 4 1\n"
785 "X_COORDINATES 4 float 0 1 2 3\n"
786 "Y_COORDINATES 4 float 0 1 2 3\n"
787 "Z_COORDINATES 1 float 0\n";
788
789 return test_structured_2d( file );
790 }
791
test_structured_points_3d()792 bool test_structured_points_3d()
793 {
794 const char file[] =
795 "# vtk DataFile Version 3.0\n"
796 "MOAB Version 1.00\n"
797 "ASCII\n"
798 "DATASET STRUCTURED_POINTS\n"
799 "DIMENSIONS 3 3 3\n"
800 "ORIGIN 0 0 0\n"
801 "SPACING 1 1 1\n";
802 return test_structured_3d( file );
803 }
804
test_structured_grid_3d()805 bool test_structured_grid_3d()
806 {
807 char file[4096] =
808 "# vtk DataFile Version 3.0\n"
809 "MOAB Version 1.00\n"
810 "ASCII\n"
811 "DATASET STRUCTURED_GRID\n"
812 "DIMENSIONS 3 3 3\n"
813 "POINTS 27 double\n";
814
815 int len = strlen(file);
816 for (unsigned i = 0; i < 27; ++i)
817 len += sprintf(file+len, "%f %f %f\n", grid_2x2x2[3*i], grid_2x2x2[3*i+1], grid_2x2x2[3*i+2]);
818
819 return test_structured_3d( file );
820 }
821
test_rectilinear_grid_3d()822 bool test_rectilinear_grid_3d()
823 {
824 const char file[] =
825 "# vtk DataFile Version 3.0\n"
826 "MOAB Version 1.00\n"
827 "ASCII\n"
828 "DATASET RECTILINEAR_GRID\n"
829 "DIMENSIONS 3 3 3\n"
830 "X_COORDINATES 3 float 0 1 2\n"
831 "Y_COORDINATES 3 float 0 1 2\n"
832 "Z_COORDINATES 3 float 0 1 2\n";
833
834 return test_structured_3d( file );
835 }
836
837 bool test_scalar_attrib(const char* vtk_type, DataType mb_type, int count);
838 bool test_vector_attrib(const char* vtk_type, DataType mb_type);
839 bool test_tensor_attrib(const char* vtk_type, DataType mb_type);
840
test_scalar_attrib_1_bit()841 bool test_scalar_attrib_1_bit()
842 {
843 return test_scalar_attrib("bit", MB_TYPE_BIT, 1);
844 }
845
test_scalar_attrib_1_uchar()846 bool test_scalar_attrib_1_uchar()
847 {
848 return test_scalar_attrib("unsigned_char", MB_TYPE_INTEGER, 1);
849 }
850
test_scalar_attrib_1_char()851 bool test_scalar_attrib_1_char()
852 {
853 return test_scalar_attrib("char", MB_TYPE_INTEGER, 1);
854 }
855
test_scalar_attrib_1_ushort()856 bool test_scalar_attrib_1_ushort()
857 {
858 return test_scalar_attrib("unsigned_short", MB_TYPE_INTEGER, 1);
859 }
860
test_scalar_attrib_1_short()861 bool test_scalar_attrib_1_short()
862 {
863 return test_scalar_attrib("short", MB_TYPE_INTEGER, 1);
864 }
865
test_scalar_attrib_1_uint()866 bool test_scalar_attrib_1_uint()
867 {
868 return test_scalar_attrib("unsigned_int", MB_TYPE_INTEGER, 1);
869 }
870
test_scalar_attrib_1_int()871 bool test_scalar_attrib_1_int()
872 {
873 return test_scalar_attrib("int", MB_TYPE_INTEGER, 1);
874 }
875
test_scalar_attrib_1_ulong()876 bool test_scalar_attrib_1_ulong()
877 {
878 return test_scalar_attrib("unsigned_long", MB_TYPE_INTEGER, 1);
879 }
880
test_scalar_attrib_1_long()881 bool test_scalar_attrib_1_long()
882 {
883 return test_scalar_attrib("long", MB_TYPE_INTEGER, 1);
884 }
885
test_scalar_attrib_1_float()886 bool test_scalar_attrib_1_float()
887 {
888 return test_scalar_attrib("float", MB_TYPE_DOUBLE, 1);
889 }
890
test_scalar_attrib_1_double()891 bool test_scalar_attrib_1_double()
892 {
893 return test_scalar_attrib("double", MB_TYPE_DOUBLE, 1);
894 }
895
test_scalar_attrib_4_bit()896 bool test_scalar_attrib_4_bit()
897 {
898 return test_scalar_attrib("bit", MB_TYPE_BIT, 4);
899 }
900
test_scalar_attrib_4_uchar()901 bool test_scalar_attrib_4_uchar()
902 {
903 return test_scalar_attrib("unsigned_char", MB_TYPE_INTEGER, 4);
904 }
905
test_scalar_attrib_4_char()906 bool test_scalar_attrib_4_char()
907 {
908 return test_scalar_attrib("char", MB_TYPE_INTEGER, 4);
909 }
910
test_scalar_attrib_4_ushort()911 bool test_scalar_attrib_4_ushort()
912 {
913 return test_scalar_attrib("unsigned_short", MB_TYPE_INTEGER, 4);
914 }
915
test_scalar_attrib_4_short()916 bool test_scalar_attrib_4_short()
917 {
918 return test_scalar_attrib("short", MB_TYPE_INTEGER, 4);
919 }
920
test_scalar_attrib_4_uint()921 bool test_scalar_attrib_4_uint()
922 {
923 return test_scalar_attrib("unsigned_int", MB_TYPE_INTEGER, 4);
924 }
925
test_scalar_attrib_4_int()926 bool test_scalar_attrib_4_int()
927 {
928 return test_scalar_attrib("int", MB_TYPE_INTEGER, 4);
929 }
930
test_scalar_attrib_4_ulong()931 bool test_scalar_attrib_4_ulong()
932 {
933 return test_scalar_attrib("unsigned_long", MB_TYPE_INTEGER, 4);
934 }
935
test_scalar_attrib_4_long()936 bool test_scalar_attrib_4_long()
937 {
938 return test_scalar_attrib("long", MB_TYPE_INTEGER, 4);
939 }
940
test_scalar_attrib_4_float()941 bool test_scalar_attrib_4_float()
942 {
943 return test_scalar_attrib("float", MB_TYPE_DOUBLE, 4);
944 }
945
test_scalar_attrib_4_double()946 bool test_scalar_attrib_4_double()
947 {
948 return test_scalar_attrib("double", MB_TYPE_DOUBLE, 4);
949 }
950
test_vector_attrib_bit()951 bool test_vector_attrib_bit()
952 {
953 return test_vector_attrib("bit", MB_TYPE_BIT);
954 }
955
test_vector_attrib_uchar()956 bool test_vector_attrib_uchar()
957 {
958 return test_vector_attrib("unsigned_char", MB_TYPE_INTEGER);
959 }
960
test_vector_attrib_char()961 bool test_vector_attrib_char()
962 {
963 return test_vector_attrib("char", MB_TYPE_INTEGER);
964 }
965
test_vector_attrib_ushort()966 bool test_vector_attrib_ushort()
967 {
968 return test_vector_attrib("unsigned_short", MB_TYPE_INTEGER);
969 }
970
test_vector_attrib_short()971 bool test_vector_attrib_short()
972 {
973 return test_vector_attrib("short", MB_TYPE_INTEGER);
974 }
975
test_vector_attrib_uint()976 bool test_vector_attrib_uint()
977 {
978 return test_vector_attrib("unsigned_int", MB_TYPE_INTEGER);
979 }
980
test_vector_attrib_int()981 bool test_vector_attrib_int()
982 {
983 return test_vector_attrib("int", MB_TYPE_INTEGER);
984 }
985
test_vector_attrib_ulong()986 bool test_vector_attrib_ulong()
987 {
988 return test_vector_attrib("unsigned_long", MB_TYPE_INTEGER);
989 }
990
test_vector_attrib_long()991 bool test_vector_attrib_long()
992 {
993 return test_vector_attrib("long", MB_TYPE_INTEGER);
994 }
995
test_vector_attrib_float()996 bool test_vector_attrib_float()
997 {
998 return test_vector_attrib("float", MB_TYPE_DOUBLE);
999 }
1000
test_vector_attrib_double()1001 bool test_vector_attrib_double()
1002 {
1003 return test_vector_attrib("double", MB_TYPE_DOUBLE);
1004 }
1005
test_tensor_attrib_uchar()1006 bool test_tensor_attrib_uchar()
1007 {
1008 return test_tensor_attrib("unsigned_char", MB_TYPE_INTEGER);
1009 }
1010
test_tensor_attrib_char()1011 bool test_tensor_attrib_char()
1012 {
1013 return test_tensor_attrib("char", MB_TYPE_INTEGER);
1014 }
1015
test_tensor_attrib_ushort()1016 bool test_tensor_attrib_ushort()
1017 {
1018 return test_tensor_attrib("unsigned_short", MB_TYPE_INTEGER);
1019 }
1020
test_tensor_attrib_short()1021 bool test_tensor_attrib_short()
1022 {
1023 return test_tensor_attrib("short", MB_TYPE_INTEGER);
1024 }
1025
test_tensor_attrib_uint()1026 bool test_tensor_attrib_uint()
1027 {
1028 return test_tensor_attrib("unsigned_int", MB_TYPE_INTEGER);
1029 }
1030
test_tensor_attrib_int()1031 bool test_tensor_attrib_int()
1032 {
1033 return test_tensor_attrib("int", MB_TYPE_INTEGER);
1034 }
1035
test_tensor_attrib_ulong()1036 bool test_tensor_attrib_ulong()
1037 {
1038 return test_tensor_attrib("unsigned_long", MB_TYPE_INTEGER);
1039 }
1040
test_tensor_attrib_long()1041 bool test_tensor_attrib_long()
1042 {
1043 return test_tensor_attrib("long", MB_TYPE_INTEGER);
1044 }
1045
test_tensor_attrib_float()1046 bool test_tensor_attrib_float()
1047 {
1048 return test_tensor_attrib("float", MB_TYPE_DOUBLE);
1049 }
1050
test_tensor_attrib_double()1051 bool test_tensor_attrib_double()
1052 {
1053 return test_tensor_attrib("double", MB_TYPE_DOUBLE);
1054 }
1055
read_file(Interface * iface,const char * file)1056 bool read_file( Interface* iface, const char* file )
1057 {
1058 char fname[] = "tmp_file.vtk";
1059 FILE* fptr = fopen( fname, "w" );
1060 fputs( file, fptr );
1061 fclose( fptr );
1062
1063 ErrorCode rval = iface->load_mesh( fname );
1064 remove( fname );
1065 CHECK(rval);
1066 return true;
1067 }
1068
write_and_read(Interface * iface1,Interface * iface2)1069 bool write_and_read( Interface* iface1, Interface* iface2 )
1070 {
1071 const char fname[] = "tmp_file.vtk";
1072 ErrorCode rval1 = iface1->write_mesh( fname );
1073 ErrorCode rval2 = iface2->load_mesh( fname );
1074 remove( fname );
1075 CHECK(rval1);
1076 CHECK(rval2);
1077 return true;
1078 }
1079
compare_connectivity(EntityType,const int * conn1,const int * conn2,unsigned len)1080 bool compare_connectivity( EntityType ,
1081 const int* conn1,
1082 const int* conn2,
1083 unsigned len )
1084 {
1085 for (unsigned i = 0; i < len; ++i)
1086 if (conn1[i] != conn2[i])
1087 return false;
1088 return true;
1089 }
1090
match_vertices_and_elements(Interface * iface,EntityType moab_type,unsigned num_vert,unsigned num_elem,unsigned vert_per_elem,const double * coords,const int * connectivity,EntityHandle * vert_handles,EntityHandle * elem_handles)1091 bool match_vertices_and_elements( Interface* iface,
1092 EntityType moab_type,
1093 unsigned num_vert,
1094 unsigned num_elem,
1095 unsigned vert_per_elem,
1096 const double* coords,
1097 const int* connectivity,
1098 EntityHandle* vert_handles,
1099 EntityHandle* elem_handles )
1100 {
1101 ErrorCode rval;
1102
1103 // get vertices and check count
1104 Range verts;
1105 rval = iface->get_entities_by_type( 0, MBVERTEX, verts );
1106 CHECK(rval);
1107 CHECK(verts.size() == num_vert);
1108
1109 // get elements and check count
1110 Range elems;
1111 rval = iface->get_entities_by_type( 0, moab_type, elems );
1112 CHECK(rval);
1113 CHECK(elems.size() == num_elem);
1114
1115 // get vertex coordinates
1116 std::vector<EntityHandle> vert_array(num_vert);
1117 std::copy(verts.begin(), verts.end(), vert_array.begin());
1118 std::vector<double> mb_coords(3*num_vert);
1119 rval = iface->get_coords( &vert_array[0], num_vert, &mb_coords[0] );
1120 CHECK(rval);
1121
1122 // compare vertex coordinates to construct map from
1123 // EntityHandle to index in input coordinate list
1124 std::map<EntityHandle,int> vert_map;
1125 std::vector<bool> seen(num_vert, false);
1126 for (unsigned i = 0; i < num_vert; ++i) {
1127 double* vert_coords = &mb_coords[3*i];
1128 bool found = false;
1129 for (unsigned j = 0; j < num_vert; ++j) {
1130 const double* file_coords = &coords[3*j];
1131 double dsqr = 0;
1132 for (unsigned k = 0; k < 3; ++k) {
1133 double diff = vert_coords[k] - file_coords[k];
1134 dsqr += diff*diff;
1135 }
1136 if (dsqr < 1e-6) {
1137 CHECK(!seen[j]); // duplicate vertex
1138 seen[j] = found = true;
1139 vert_map[vert_array[i]] = j;
1140 vert_handles[j] = vert_array[i];
1141 break;
1142 }
1143 }
1144 CHECK(found); // not found?
1145 }
1146
1147 // check element connectivity
1148 seen.clear(); seen.resize( num_elem, false );
1149 Range::iterator iter = elems.begin();
1150 for (unsigned i = 0; i < num_elem; ++i) {
1151 // get element connectivity
1152 EntityHandle elem = *iter; ++iter;
1153 std::vector<EntityHandle> elem_conn;
1154 rval = iface->get_connectivity( &elem, 1, elem_conn );
1155 CHECK(rval);
1156 CHECK( elem_conn.size() == vert_per_elem );
1157
1158 // convert to input vertex ordering
1159 std::vector<int> elem_conn2(vert_per_elem);
1160 for (unsigned j = 0; j < vert_per_elem; ++j) {
1161 std::map<EntityHandle,int>::iterator k = vert_map.find(elem_conn[j]);
1162 CHECK( k != vert_map.end() );
1163 elem_conn2[j] = k->second;
1164 }
1165
1166 // search input list for matching element
1167 bool found = false;
1168 for (unsigned j = 0; j < num_elem; ++j) {
1169 const int* conn_arr = connectivity + j*vert_per_elem;
1170 if (!seen[j] &&
1171 compare_connectivity( moab_type, conn_arr, &elem_conn2[0], vert_per_elem))
1172 {
1173 seen[j] = found = true;
1174 elem_handles[j] = elem;
1175 break;
1176 }
1177 }
1178 CHECK(found);
1179 }
1180
1181 return true;
1182 }
1183
check_elements(Interface * iface,EntityType moab_type,unsigned num_elem,unsigned vert_per_elem,const double * coords,unsigned num_vert,const int * connectivity)1184 bool check_elements( Interface* iface,
1185 EntityType moab_type, unsigned num_elem, unsigned vert_per_elem,
1186 const double* coords, unsigned num_vert,
1187 const int* connectivity )
1188 {
1189 std::vector<EntityHandle> junk1(num_vert), junk2(num_elem);
1190 bool rval = match_vertices_and_elements( iface, moab_type, num_vert, num_elem,
1191 vert_per_elem, coords, connectivity,
1192 &junk1[0], &junk2[0] );
1193 CHECK(rval);
1194 return true;
1195 }
1196
test_read_write_element(const double * coords,unsigned num_verts,const int * vtk_conn,const int * moab_conn,unsigned num_conn,unsigned num_elem,unsigned vtk_type,EntityType moab_type)1197 bool test_read_write_element( const double* coords, unsigned num_verts,
1198 const int* vtk_conn, const int* moab_conn,
1199 unsigned num_conn,
1200 unsigned num_elem, unsigned vtk_type,
1201 EntityType moab_type )
1202
1203 {
1204 // construct VTK file
1205 char file[4096] =
1206 "# vtk DataFile Version 3.0\n"
1207 "MOAB Version 1.00\n"
1208 "ASCII\n"
1209 "DATASET UNSTRUCTURED_GRID\n";
1210 size_t len = strlen(file);
1211
1212 len += sprintf(file+len, "POINTS %u double\n", num_verts);
1213 for (unsigned i = 0; i < num_verts; ++i)
1214 len += sprintf(file+len, "%f %f %f\n", coords[3*i], coords[3*i+1], coords[3*i+2] );
1215
1216 len += sprintf(file+len, "CELLS %u %u\n", num_elem, num_conn+num_elem);
1217 assert( num_conn % num_elem == 0 );
1218 unsigned conn_len = num_conn / num_elem;
1219 for (unsigned i = 0; i < num_elem; ++i) {
1220 len += sprintf(file+len, "%u", conn_len );
1221 for (unsigned j = 0; j < conn_len; ++j)
1222 len += sprintf(file+len, " %u", vtk_conn[conn_len*i+j]);
1223 len += sprintf(file+len,"\n");
1224 }
1225
1226 len += sprintf(file+len,"CELL_TYPES %u\n", num_elem);
1227 for (unsigned i =0; i < num_elem; ++i)
1228 len += sprintf(file+len, "%u\n", vtk_type);
1229
1230 // read VTK file and check results
1231 Core instance1, instance2;
1232 bool bval = read_file( &instance1, file ); CHECK(bval);
1233 bval = check_elements( &instance1, moab_type, num_elem, conn_len, coords, num_verts, moab_conn );
1234 CHECK(bval);
1235
1236 // write, re-read, and check results
1237 bval = write_and_read( &instance1, &instance2 ); CHECK(bval);
1238 bval = check_elements( &instance2, moab_type, num_elem, conn_len, coords, num_verts, moab_conn );
1239 CHECK(bval);
1240
1241 return true;
1242 }
1243
test_structured_2d(const char * file)1244 bool test_structured_2d( const char* file )
1245 {
1246 // read VTK file and check results
1247 Core instance;
1248 bool bval = read_file( &instance, file ); CHECK(bval);
1249 bval = check_elements( &instance, MBQUAD, 9, 4, grid_3x3, 16, quad_structured_conn );
1250 CHECK(bval);
1251
1252 return true;
1253 }
1254
test_structured_3d(const char * file)1255 bool test_structured_3d( const char* file )
1256 {
1257 // read VTK file and check results
1258 Core instance;
1259 bool bval = read_file( &instance, file ); CHECK(bval);
1260 bval = check_elements( &instance, MBHEX, 8, 8, grid_2x2x2, 27, hex_structured_conn );
1261 CHECK(bval);
1262
1263 return true;
1264 }
1265
1266 const char two_quad_mesh[] =
1267 "# vtk DataFile Version 3.0\n"
1268 "MOAB Version 1.00\n"
1269 "ASCII\n"
1270 "DATASET UNSTRUCTURED_GRID\n"
1271 "POINTS 6 float\n"
1272 "-1 0 0\n"
1273 " 0 0 0\n"
1274 " 1 0 0\n"
1275 "-1 1 0\n"
1276 " 0 1 0\n"
1277 " 1 1 0\n"
1278 "CELLS 2 10\n"
1279 "4 0 1 4 3\n"
1280 "4 1 2 5 4\n"
1281 "CELL_TYPES 2\n"
1282 "9 9\n";
1283
1284 const double two_quad_mesh_coords[] = {
1285 -1, 0, 0,
1286 0, 0, 0,
1287 1, 0, 0,
1288 -1, 1, 0,
1289 0, 1, 0,
1290 1, 1, 0 };
1291 const int two_quad_mesh_conn[] = {
1292 0, 1, 4, 3,
1293 1, 2, 5, 4 };
1294
1295 const int vertex_values[] = { 9, 3, 8, 2, 0, 6,
1296 4, 1, 4, 1, 0, 3,
1297 8, 6, 6, 4, 0, 2,
1298 1, 2, 3, 4, 5, 6,
1299 6, 5, 4, 3, 2, 1,
1300 0, 6, 1, 5, 2, 4,
1301 3, 6, 9, 2, 5, 8,
1302 1, 3, 5, 7, 1, 3,
1303 5, 8, 1, 9, 7, 4 };
1304 const int element_values[] = { 1001, 1002, 1004, 1003, 50, 60, 51, 61,
1305 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1306 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
1307
write_data(char * file,size_t & len,DataType type,unsigned count,const int * vals)1308 void write_data( char* file, size_t& len, DataType type, unsigned count, const int* vals )
1309 {
1310 switch(type) {
1311 case MB_TYPE_BIT:
1312 for (unsigned i = 0; i < count; ++i)
1313 len += sprintf(file+len, "%d\n", abs(vals[i])%2);
1314 break;
1315 case MB_TYPE_INTEGER:
1316 for (unsigned i = 0; i < count; ++i)
1317 len += sprintf(file+len, "%d\n", vals[i]);
1318 break;
1319 case MB_TYPE_DOUBLE:
1320 for (unsigned i = 0; i < count; ++i)
1321 len += sprintf(file+len, "%f\n", (double)vals[i]);
1322 break;
1323 case MB_TYPE_OPAQUE:
1324 for (unsigned i = 0; i < count; ++i)
1325 len += sprintf(file+len, "%d\n", abs(vals[i]%256));
1326 break;
1327 default:
1328 assert( false /* VTK files cannot handle this type */ );
1329 }
1330 }
1331
check_tag_values(Interface * iface,DataType tag_type,int tag_length,int num_entities,const EntityHandle * entities,const int * values)1332 bool check_tag_values( Interface* iface,
1333 DataType tag_type, int tag_length,
1334 int num_entities, const EntityHandle* entities,
1335 const int* values )
1336 {
1337 Tag tag;
1338 ErrorCode rval = iface->tag_get_handle( "data", tag_length, tag_type, tag ); CHECK(rval);
1339
1340 int size, *intptr;
1341 double* dblptr;
1342 rval = iface->tag_get_bytes( tag, size ); CHECK(rval);
1343 std::vector<unsigned char> data( size * num_entities );
1344
1345 switch (tag_type) {
1346 case MB_TYPE_BIT:
1347 rval = iface->tag_get_length( tag, size ); CHECK(rval);
1348 CHECK( tag_length == size );
1349 for (int i = 0; i < num_entities; ++i) {
1350 unsigned char val;
1351 rval = iface->tag_get_data( tag, entities + i, 1, &val ); CHECK(rval);
1352 for (int j = 0; j < tag_length; ++j) {
1353 int bitval = !!(val & (1 << j));
1354 int expval = abs(*values) % 2;
1355 CHECK( bitval == expval );
1356 ++values;
1357 }
1358 }
1359 break;
1360 case MB_TYPE_OPAQUE:
1361 rval = iface->tag_get_data( tag, entities, num_entities, &data[0] ); CHECK(rval);
1362 CHECK( tag_length == size );
1363 for (int i = 0; i < num_entities; ++i)
1364 for (int j = 0; j < tag_length; ++j, ++values)
1365 CHECK( (unsigned)(*values % 256) == data[i*tag_length+j] );
1366 break;
1367 case MB_TYPE_INTEGER:
1368 rval = iface->tag_get_data( tag, entities, num_entities, &data[0] ); CHECK(rval);
1369 CHECK( tag_length*sizeof(int) == (unsigned)size );
1370 intptr = reinterpret_cast<int*>(&data[0]);
1371 for (int i = 0; i < num_entities; ++i)
1372 for (int j = 0; j < tag_length; ++j, ++values)
1373 CHECK( *values == intptr[i*tag_length+j] );
1374 break;
1375 case MB_TYPE_DOUBLE:
1376 rval = iface->tag_get_data( tag, entities, num_entities, &data[0] ); CHECK(rval);
1377 CHECK( tag_length*sizeof(double) == (unsigned)size );
1378 dblptr = reinterpret_cast<double*>(&data[0]);
1379 for (int i = 0; i < num_entities; ++i)
1380 for (int j = 0; j < tag_length; ++j, ++values)
1381 CHECK( *values == dblptr[i*tag_length+j] );
1382 break;
1383 default:
1384 assert(false);
1385 return false;
1386 }
1387 return true;
1388 }
1389
check_tag_values(Interface * iface,DataType type,int vals_per_ent)1390 bool check_tag_values( Interface* iface, DataType type, int vals_per_ent )
1391 {
1392 EntityHandle vert_handles[6], elem_handles[2];
1393 bool rval = match_vertices_and_elements( iface, MBQUAD, 6, 2, 4,
1394 two_quad_mesh_coords, two_quad_mesh_conn,
1395 vert_handles, elem_handles ); CHECK(rval);
1396
1397 rval = check_tag_values( iface, type, vals_per_ent, 6, vert_handles, vertex_values );
1398 CHECK(rval);
1399 rval = check_tag_values( iface, type, vals_per_ent, 2, elem_handles, element_values );
1400 CHECK(rval);
1401 return rval;
1402 }
1403
check_tag_data(const char * file,DataType type,int vals_per_ent)1404 bool check_tag_data( const char* file, DataType type, int vals_per_ent )
1405 {
1406 bool bval;
1407 Core instance1, instance2;
1408
1409 bval = read_file( &instance1, file ); CHECK(bval);
1410 bval = check_tag_values( &instance1, type, vals_per_ent ); CHECK(bval);
1411 bval = write_and_read( &instance1, &instance2 ); CHECK(bval);
1412 bval = check_tag_values( &instance2, type, vals_per_ent ); CHECK(bval);
1413 return true;
1414 }
1415
test_scalar_attrib(const char * vtk_type,DataType mb_type,int count)1416 bool test_scalar_attrib(const char* vtk_type, DataType mb_type, int count)
1417 {
1418 char file[4096];
1419 strcpy( file, two_quad_mesh );
1420 size_t len = strlen(file);
1421 len += sprintf(file+len, "POINT_DATA 6\n");
1422 len += sprintf(file+len, "SCALARS data %s %d\n", vtk_type, count );
1423 len += sprintf(file+len, "LOOKUP_TABLE default\n");
1424 write_data( file, len, mb_type, 6*count, vertex_values );
1425 len += sprintf(file+len, "CELL_DATA 2\n");
1426 len += sprintf(file+len, "SCALARS data %s %d\n", vtk_type, count );
1427 len += sprintf(file+len, "LOOKUP_TABLE default\n");
1428 write_data( file, len, mb_type, 2*count, element_values );
1429
1430 return check_tag_data( file, mb_type, count );
1431 }
1432
test_vector_attrib(const char * vtk_type,DataType mb_type)1433 bool test_vector_attrib( const char* vtk_type, DataType mb_type )
1434 {
1435 char file[4096];
1436 strcpy( file, two_quad_mesh );
1437 size_t len = strlen(file);
1438 len += sprintf(file+len, "POINT_DATA 6\n");
1439 len += sprintf(file+len, "VECTORS data %s\n", vtk_type );
1440 write_data( file, len, mb_type, 6*3, vertex_values );
1441 len += sprintf(file+len, "CELL_DATA 2\n");
1442 len += sprintf(file+len, "VECTORS data %s\n", vtk_type );
1443 write_data( file, len, mb_type, 2*3, element_values );
1444
1445 return check_tag_data( file, mb_type, 3 );
1446 }
1447
test_tensor_attrib(const char * vtk_type,DataType mb_type)1448 bool test_tensor_attrib( const char* vtk_type, DataType mb_type )
1449 {
1450 char file[4096];
1451 strcpy( file, two_quad_mesh );
1452 size_t len = strlen(file);
1453 len += sprintf(file+len, "POINT_DATA 6\n");
1454 len += sprintf(file+len, "TENSORS data %s\n", vtk_type );
1455 write_data( file, len, mb_type, 6*9, vertex_values );
1456 len += sprintf(file+len, "CELL_DATA 2\n");
1457 len += sprintf(file+len, "TENSORS data %s\n", vtk_type );
1458 write_data( file, len, mb_type, 2*9, element_values );
1459
1460 return check_tag_data( file, mb_type, 9 );
1461 }
1462
test_subset()1463 bool test_subset()
1464 {
1465 Core moab_inst;
1466 Interface& moab = moab_inst;
1467 ErrorCode rval;
1468
1469 // create 9 nodes in grid pattern
1470 EntityHandle verts[9];
1471 const double coords[][3] = { { 0, 0, 0 },
1472 { 1, 0, 0 },
1473 { 2, 0, 0 },
1474 { 0, 1, 0 },
1475 { 1, 1, 0 },
1476 { 2, 1, 0 },
1477 { 0, 2, 0 },
1478 { 1, 2, 0 },
1479 { 2, 2, 0 } };
1480 for (unsigned i = 0; i < 9; ++i) {
1481 rval = moab.create_vertex(coords[i], verts[i]);
1482 assert(MB_SUCCESS == rval);
1483 }
1484
1485 // create 4 quad elements in grid pattern
1486 const int conn[][4] = { { 0, 1, 4, 3 },
1487 { 1, 2, 5, 4 },
1488 { 3, 4, 7, 6 },
1489 { 4, 5, 8, 7 } };
1490 EntityHandle econn[4], elems[4];
1491 for (unsigned i = 0; i < 4; ++i) {
1492 for (unsigned j = 0; j < 4; ++j)
1493 econn[j] = verts[conn[i][j]];
1494 rval = moab.create_element( MBQUAD, econn, 4, elems[i] );
1495 assert(MB_SUCCESS == rval);
1496 }
1497
1498 // create 3 meshsets
1499 EntityHandle sets[3];
1500 for (unsigned i = 0;i < 3; ++i) {
1501 rval = moab.create_meshset( 0, sets[i] );
1502 assert(MB_SUCCESS == rval);
1503 }
1504
1505 // add element 3 to set 0
1506 rval = moab.add_entities( sets[0], elems+3, 1 );
1507 assert(MB_SUCCESS == rval);
1508 // add node 2 to set 1
1509 rval = moab.add_entities( sets[1], verts+2, 1 );
1510 assert(MB_SUCCESS == rval);
1511 // add element 2 and 3 to set 2
1512 rval = moab.add_entities( sets[2], elems+2, 2 );
1513 assert(MB_SUCCESS == rval);
1514
1515 // make set 2 a child of set 1
1516 rval = moab.add_child_meshset( sets[1], sets[2] );
1517 assert(MB_SUCCESS == rval);
1518 // put set 1 in set 0
1519 rval = moab.add_entities( sets[0], sets+1, 1 );
1520 assert(MB_SUCCESS == rval);
1521
1522 // write sets[0] to vtk file
1523 rval = moab.write_mesh( "tmp_file.vtk", sets, 1 );
1524 CHECK(rval);
1525
1526 // read data back in
1527 moab.delete_mesh();
1528 rval = moab.load_mesh( "tmp_file.vtk" );
1529 remove( "tmp_file.vtk" );
1530 CHECK(rval);
1531
1532 // writer should have written all three sets,
1533 // so the resulting mesh should be elems[2], elems[3],
1534 // and verts[2]
1535 Range new_elems, new_verts;
1536 rval = moab.get_entities_by_type( 0, MBQUAD, new_elems );
1537 CHECK(rval);
1538 CHECK( new_elems.size() == 2 );
1539 rval = moab.get_entities_by_type( 0, MBVERTEX, new_verts );
1540 CHECK(rval);
1541 CHECK( new_verts.size() == 7 );
1542
1543 // vertex not in element closure should have coords of 2,0,0
1544 Range elem_verts;
1545 rval = moab.get_adjacencies( new_elems, 0, false, elem_verts, Interface::UNION );
1546 CHECK(rval);
1547 CHECK(elem_verts.size() == 6);
1548 Range free_verts( subtract( new_verts, elem_verts ) );
1549 CHECK(free_verts.size() == 1 );
1550 double vcoords[3];
1551 rval = moab.get_coords( free_verts, vcoords );
1552 CHECK( vcoords[0] == 2 );
1553 CHECK( vcoords[1] == 0 );
1554 CHECK( vcoords[2] == 0 );
1555
1556 return true;
1557 }
1558
test_write_free_nodes()1559 bool test_write_free_nodes()
1560 {
1561 Core moab_inst;
1562 Interface& moab = moab_inst;
1563 ErrorCode rval;
1564
1565 // create 9 nodes in grid pattern
1566 EntityHandle verts[9];
1567 const double coords[][3] = { { 0, 0, 0 },
1568 { 1, 0, 0 },
1569 { 2, 0, 0 },
1570 { 0, 1, 0 },
1571 { 1, 1, 0 },
1572 { 2, 1, 0 },
1573 { 0, 2, 0 },
1574 { 1, 2, 0 },
1575 { 2, 2, 0 } };
1576 for (unsigned i = 0; i < 9; ++i) {
1577 rval = moab.create_vertex(coords[i], verts[i]);
1578 assert(MB_SUCCESS == rval);
1579 }
1580
1581 // create 3 quad elements, one node (8) not used
1582 const int conn[][4] = { { 0, 1, 4, 3 },
1583 { 1, 2, 5, 4 },
1584 { 3, 4, 7, 6 }};
1585
1586 Tag gid;
1587 rval = moab.tag_get_handle("GLOBAL_ID", 1, moab::MB_TYPE_INTEGER, gid);
1588 assert(MB_SUCCESS == rval);
1589 EntityHandle econn[4], elems[3];
1590 for (unsigned i = 0; i < 3; ++i) {
1591 for (unsigned j = 0; j < 4; ++j)
1592 econn[j] = verts[conn[i][j]];
1593 rval = moab.create_element( MBQUAD, econn, 4, elems[i] );
1594 assert(MB_SUCCESS == rval);
1595 int id = i+1;
1596 rval = moab.tag_set_data(gid, &elems[i], 1, &id);
1597 assert(MB_SUCCESS == rval);
1598 }
1599
1600 rval = moab.write_file( "tmp_file.vtk");
1601 CHECK(rval);
1602
1603 rval = moab.write_file( "tmp_file2.vtk", 0, "CREATE_ONE_NODE_CELLS;");
1604 CHECK(rval);
1605
1606 // read data back in
1607 moab.delete_mesh();
1608 rval = moab.load_file( "tmp_file.vtk" );
1609 remove( "tmp_file.vtk" );
1610 remove( "tmp_file2.vtk" );
1611 CHECK(rval);
1612
1613 return true;
1614 }
1615
1616 // Test technically invalid but somewhat common insertion of
1617 // FIELD blocks within an UNSTRUCTURED_GRID dataset
test_unstructured_field()1618 bool test_unstructured_field()
1619 {
1620 // Use existing file defined in 'two_quad_mesh', but
1621 // insert a few field data blocks
1622 std::istringstream base_data( two_quad_mesh );
1623 std::ostringstream file_data;
1624 std::string line;
1625 while (getline( base_data, line )) {
1626 if (0 == line.find("POINTS")) {
1627 file_data << "FIELD FieldData 2" << std::endl
1628 << "avtOriginalBounds 1 6 float" << std::endl
1629 << "-10 10 -10 10 -10 10 " << std::endl
1630 << "TIME 1 1 double" << std::endl
1631 << "10.543" << std::endl;
1632 }
1633 else if (0 == line.find("CELLS")) {
1634 file_data << "FIELD more_data 2" << std::endl
1635 << "first_array 3 2 int" << std::endl
1636 << "0 1 2" << std::endl
1637 << "3 4 5" << std::endl
1638 << "second_array 4 3 bit" << std::endl
1639 << "0 0 0 0" << std::endl
1640 << "1 1 1 1" << std::endl
1641 << "1 0 1 0" << std::endl;
1642 }
1643 file_data << line << std::endl;
1644 }
1645
1646 Core core;
1647 Interface& mb = core;
1648 bool rval = read_file(&mb, file_data.str().c_str());
1649 CHECK(rval);
1650
1651 EntityHandle vert_handles[6], elem_handles[2];
1652 rval = match_vertices_and_elements( &mb, MBQUAD, 6, 2, 4,
1653 two_quad_mesh_coords, two_quad_mesh_conn,
1654 vert_handles, elem_handles );
1655 CHECK(rval);
1656
1657 return true;
1658 }
1659