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