1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2004 Lawrence Livermore National Laboratory.  Under
5     the terms of Contract B545069 with the University of Wisconsin --
6     Madison, Lawrence Livermore National Laboratory retains certain
7     rights in this software.
8 
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Lesser General Public
11     License as published by the Free Software Foundation; either
12     version 2.1 of the License, or (at your option) any later version.
13 
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Lesser General Public License for more details.
18 
19     You should have received a copy of the GNU Lesser General Public License
20     (lgpl.txt) along with this library; if not, write to the Free Software
21     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 
23     kraftche@cae.wisc.edu
24 
25   ***************************************************************** */
26 
27 #include <algorithm>
28 #include <iostream>
29 using std::cout;
30 #include "cppunit/extensions/HelperMacros.h"
31 
32 #include "Mesquite.hpp"
33 #include "MsqError.hpp"
34 #include "TopologyInfo.hpp"
35 
36 using namespace MBMesquite;
37 
38 class TopologyInfoTest : public CppUnit::TestFixture
39 {
40 private:
41    CPPUNIT_TEST_SUITE(TopologyInfoTest);
42 
43    CPPUNIT_TEST (tri);
44    CPPUNIT_TEST (tri3);
45    CPPUNIT_TEST (tri4);
46    CPPUNIT_TEST (tri6);
47    CPPUNIT_TEST (tri7);
48 
49    CPPUNIT_TEST (quad);
50    CPPUNIT_TEST (quad4);
51    CPPUNIT_TEST (quad5);
52    CPPUNIT_TEST (quad8);
53    CPPUNIT_TEST (quad9);
54 
55    CPPUNIT_TEST (tet);
56    CPPUNIT_TEST (tet4);
57    CPPUNIT_TEST (tet5);
58    CPPUNIT_TEST (tet8);
59    CPPUNIT_TEST (tet9);
60    CPPUNIT_TEST (tet10);
61    CPPUNIT_TEST (tet11);
62    CPPUNIT_TEST (tet14);
63    CPPUNIT_TEST (tet15);
64 
65    CPPUNIT_TEST (hex);
66    CPPUNIT_TEST (hex8);
67    CPPUNIT_TEST (hex9);
68    CPPUNIT_TEST (hex14);
69    CPPUNIT_TEST (hex15);
70    CPPUNIT_TEST (hex20);
71    CPPUNIT_TEST (hex21);
72    CPPUNIT_TEST (hex26);
73    CPPUNIT_TEST (hex27);
74 
75    CPPUNIT_TEST (pyramid);
76    CPPUNIT_TEST (pyramid5);
77    CPPUNIT_TEST (pyramid13);
78 
79    CPPUNIT_TEST (wedge);
80    CPPUNIT_TEST (wedge6);
81    CPPUNIT_TEST (wedge15);
82 
83    CPPUNIT_TEST (polygon);
84    CPPUNIT_TEST (polyhedron);
85 
86    CPPUNIT_TEST (bad_type);
87 
88    CPPUNIT_TEST (tri_adj_vert);
89    CPPUNIT_TEST (quad_adj_vert);
90    CPPUNIT_TEST (tet_adj_vert);
91    CPPUNIT_TEST (hex_adj_vert);
92    CPPUNIT_TEST (pyr_adj_vert);
93    CPPUNIT_TEST (wdg_adj_vert);
94 
95    CPPUNIT_TEST (tri_rev_adj_vert);
96    CPPUNIT_TEST (quad_rev_adj_vert);
97    CPPUNIT_TEST (tet_rev_adj_vert);
98    CPPUNIT_TEST (hex_rev_adj_vert);
99    CPPUNIT_TEST (pyr_rev_adj_vert);
100    CPPUNIT_TEST (wdg_rev_adj_vert);
101 
102    CPPUNIT_TEST (higher_order_from_side);
103    CPPUNIT_TEST (side_from_higher_order);
104    CPPUNIT_TEST (find_edge);
105    CPPUNIT_TEST (find_face);
106    CPPUNIT_TEST (find_side);
107    CPPUNIT_TEST (compare_sides);
108 
109    CPPUNIT_TEST_SUITE_END();
110 
111 public:
112 
setUp()113   void setUp() {}
114 
tearDown()115   void tearDown() {}
116 
TopologyInfoTest()117   TopologyInfoTest() {}
118 
119   bool compare_edge( const unsigned* a, const unsigned* b );
120 
121   bool compare_face( unsigned len, const unsigned* a, const unsigned* b );
122 
123   bool compare_vol( unsigned len, const unsigned* a, const unsigned* b );
124 
125   void test_face_elem( EntityTopology topo,
126                        unsigned num_nodes,
127                        unsigned num_sides );
128 
129 
130   void test_vol_elem( EntityTopology topo,
131                       unsigned num_nodes,
132                       unsigned num_verts,
133                       unsigned num_edges,
134                       unsigned num_faces );
135 
136   void test_poly( EntityTopology topo );
137 
138   void tri();
139   void tri3();
140   void tri4();
141   void tri6();
142   void tri7();
143 
144   void quad();
145   void quad4();
146   void quad5();
147   void quad8();
148   void quad9();
149 
150   void tet();
151   void tet4();
152   void tet5();
153   void tet8();
154   void tet9();
155   void tet10();
156   void tet11();
157   void tet14();
158   void tet15();
159 
160   void hex();
161   void hex8();
162   void hex9();
163   void hex14();
164   void hex15();
165   void hex20();
166   void hex21();
167   void hex26();
168   void hex27();
169 
170   void pyramid();
171   void pyramid5();
172   void pyramid13();
173 
174   void wedge();
175   void wedge6();
176   void wedge15();
177 
178   void polygon();
179   void polyhedron();
180 
181   void bad_type();
182 
183   void tri_adj_vert();
184   void quad_adj_vert();
185   void tet_adj_vert();
186   void hex_adj_vert();
187   void pyr_adj_vert();
188   void wdg_adj_vert();
189   void test_adj( MBMesquite::EntityTopology, const unsigned expected[][5] );
190 
tri_rev_adj_vert()191   void tri_rev_adj_vert()  { test_rev_adj( MBMesquite::TRIANGLE      ); }
quad_rev_adj_vert()192   void quad_rev_adj_vert() { test_rev_adj( MBMesquite::QUADRILATERAL ); }
tet_rev_adj_vert()193   void tet_rev_adj_vert()  { test_rev_adj( MBMesquite::TETRAHEDRON   ); }
hex_rev_adj_vert()194   void hex_rev_adj_vert()  { test_rev_adj( MBMesquite::HEXAHEDRON    ); }
pyr_rev_adj_vert()195   void pyr_rev_adj_vert()  { test_rev_adj( MBMesquite::PYRAMID       ); }
wdg_rev_adj_vert()196   void wdg_rev_adj_vert()  { test_rev_adj( MBMesquite::PRISM         ); }
197   void test_rev_adj( MBMesquite::EntityTopology type );
198 
199   void higher_order_from_side();
200   void side_from_higher_order();
201   void find_edge();
202   void find_face();
203   void find_side();
204   void compare_sides();
205 };
206 
207 
208 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TopologyInfoTest, "TopologyInfoTest");
209 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TopologyInfoTest, "Unit");
210 
211 
212 
compare_edge(const unsigned * a,const unsigned * b)213 bool TopologyInfoTest::compare_edge( const unsigned* a, const unsigned* b )
214   { return (a[0] == b[0] && a[1] == b[1]) ||
215            (a[0] == b[1] && a[1] == b[0]); }
216 
compare_face(unsigned len,const unsigned * a,const unsigned * b)217 bool TopologyInfoTest::compare_face( unsigned len, const unsigned* a, const unsigned* b )
218 {
219   unsigned i, j;
220   for (i = 0; i < len; ++i)
221   {
222     for (j = 0; j < len; ++j)
223     {
224       if (a[j] != b[(i+j)%len])
225         break;
226     }
227     if (j == len)
228       return true;
229   }
230   return false;
231 }
232 
compare_vol(unsigned len,const unsigned * a,const unsigned * b)233 bool TopologyInfoTest::compare_vol( unsigned len, const unsigned* a, const unsigned* b )
234 {
235   for (unsigned i = 0; i < len; ++i)
236     if (a[i] != b[i])
237       return false;
238   return true;
239 }
240 
test_face_elem(EntityTopology topo,unsigned num_nodes,unsigned num_sides)241 void TopologyInfoTest::test_face_elem( EntityTopology topo,
242                      unsigned num_nodes,
243                      unsigned num_sides )
244 {
245   MsqPrintError err(cout);
246   bool edge, face, vol;
247   unsigned index = 0;
248   TopologyInfo::higher_order( topo, num_nodes, edge, face, vol , err );
249   CPPUNIT_ASSERT(!err);
250   CPPUNIT_ASSERT(!vol);
251 
252   unsigned nodes = num_sides + edge * num_sides + face;
253   CPPUNIT_ASSERT( num_nodes == nodes );
254 
255   unsigned side, dim;
256   for (index = 0; index < num_sides; ++index)
257   {
258     TopologyInfo::side_number( topo, num_nodes, index, dim, side, err );
259     CPPUNIT_ASSERT(!err);
260     CPPUNIT_ASSERT(dim == 0 && side == index);
261   }
262 
263   if (edge)
264   {
265     for (unsigned s = 0; s < num_sides; ++s)
266     {
267       TopologyInfo::side_number( topo, num_nodes, index++, dim, side, err );
268       CPPUNIT_ASSERT(!err);
269       CPPUNIT_ASSERT(dim == 1 && side == s);
270     }
271   }
272   if (face)
273   {
274     TopologyInfo::side_number( topo, num_nodes, index++, dim, side, err );
275     CPPUNIT_ASSERT(!err);
276     CPPUNIT_ASSERT(dim == 2 && side == 0);
277   }
278 }
279 
280 
test_vol_elem(EntityTopology topo,unsigned num_nodes,unsigned num_verts,unsigned num_edges,unsigned num_faces)281 void TopologyInfoTest::test_vol_elem( EntityTopology topo,
282                     unsigned num_nodes,
283                     unsigned num_verts,
284                     unsigned num_edges,
285                     unsigned num_faces )
286 {
287   MsqPrintError err(cout);
288   bool edge, face, vol;
289   unsigned index = 0;
290   TopologyInfo::higher_order( topo, num_nodes, edge, face, vol , err );
291   CPPUNIT_ASSERT(!err);
292 
293   unsigned nodes = num_verts + edge * num_edges + face * num_faces + vol;
294   CPPUNIT_ASSERT( num_nodes == nodes );
295 
296   unsigned side, dim;
297   for (index = 0; index < num_verts; ++index)
298   {
299     TopologyInfo::side_number( topo, num_nodes, index, dim, side, err );
300     CPPUNIT_ASSERT(!err);
301     CPPUNIT_ASSERT(dim == 0 && side == index);
302   }
303 
304   if (edge)
305   {
306     for (unsigned s = 0; s < num_edges; ++s)
307     {
308       TopologyInfo::side_number( topo, num_nodes, index++, dim, side, err );
309       CPPUNIT_ASSERT(!err);
310       CPPUNIT_ASSERT(dim == 1 && side == s);
311     }
312   }
313   if (face)
314   {
315     for (unsigned s = 0; s < num_faces; ++s)
316     {
317       TopologyInfo::side_number( topo, num_nodes, index++, dim, side, err );
318       CPPUNIT_ASSERT(!err);
319       CPPUNIT_ASSERT(dim == 2 && side == s);
320     }
321   }
322   if (vol)
323   {
324     TopologyInfo::side_number( topo, num_nodes, index++, dim, side, err );
325     CPPUNIT_ASSERT(!err);
326     CPPUNIT_ASSERT(dim == 3 && side == 0);
327   }
328 }
329 
330 
331 
332 
333 
tri()334 void TopologyInfoTest::tri()
335 {
336   MsqPrintError err(cout);
337 
338   CPPUNIT_ASSERT (2 == TopologyInfo::dimension( TRIANGLE ));
339   CPPUNIT_ASSERT (3 == TopologyInfo::adjacent( TRIANGLE, 1 ));
340   CPPUNIT_ASSERT (3 == TopologyInfo::adjacent( TRIANGLE, 0 ));
341   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( TRIANGLE, 2 ));
342   CPPUNIT_ASSERT (0 == TopologyInfo::adjacent( TRIANGLE, 3 ));
343 
344   CPPUNIT_ASSERT (3 == TopologyInfo::sides( TRIANGLE ));
345   CPPUNIT_ASSERT (3 == TopologyInfo::corners( TRIANGLE ));
346   CPPUNIT_ASSERT (3 == TopologyInfo::edges( TRIANGLE ));
347   CPPUNIT_ASSERT (1 == TopologyInfo::faces( TRIANGLE ));
348 
349   const unsigned num_edges = 3;
350   const unsigned* side;
351   const unsigned edges[num_edges][2] = { {0, 1}, {1, 2}, {2, 0} };
352   unsigned count;
353   const unsigned face[] = { 0, 1, 2 };
354 
355   for (unsigned i = 0; i < num_edges; ++i)
356   {
357     side = TopologyInfo::edge_vertices( TRIANGLE, i, err );
358     CPPUNIT_ASSERT(!err);
359     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
360 
361     side = TopologyInfo::side_vertices( TRIANGLE, 1, i, count, err );
362     CPPUNIT_ASSERT(!err);
363     CPPUNIT_ASSERT(2 == count);
364     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
365   }
366 
367   side = TopologyInfo::side_vertices( TRIANGLE, 2, 0, count, err );
368   CPPUNIT_ASSERT(!err);
369   CPPUNIT_ASSERT(3 == count);
370   CPPUNIT_ASSERT( compare_face( 3, side, face ) );
371 }
372 
tri3()373 void TopologyInfoTest::tri3()
374 {
375   MsqPrintError err(cout);
376   bool edge, face, vol;
377   const int num_nodes = 3;
378 
379   TopologyInfo::higher_order( TRIANGLE, num_nodes, edge, face, vol , err );
380   CPPUNIT_ASSERT(!err);
381   CPPUNIT_ASSERT(!edge);
382   CPPUNIT_ASSERT(!face);
383 
384   test_face_elem( TRIANGLE, num_nodes, 3 );
385 }
386 
tri4()387 void TopologyInfoTest::tri4()
388 {
389   MsqPrintError err(cout);
390   bool edge, face, vol;
391   const int num_nodes = 4;
392 
393   TopologyInfo::higher_order( TRIANGLE, num_nodes, edge, face, vol , err );
394   CPPUNIT_ASSERT(!err);
395   CPPUNIT_ASSERT(!edge);
396   CPPUNIT_ASSERT( face);
397   CPPUNIT_ASSERT(!vol);
398 
399   test_face_elem( TRIANGLE, num_nodes, 3 );
400 }
401 
tri6()402 void TopologyInfoTest::tri6()
403 {
404   MsqPrintError err(cout);
405   bool edge, face, vol;
406   const int num_nodes = 6;
407 
408   TopologyInfo::higher_order( TRIANGLE, num_nodes, edge, face, vol , err );
409   CPPUNIT_ASSERT(!err);
410   CPPUNIT_ASSERT( edge);
411   CPPUNIT_ASSERT(!face);
412   CPPUNIT_ASSERT(!vol);
413 
414   test_face_elem( TRIANGLE, num_nodes, 3 );
415 }
416 
tri7()417 void TopologyInfoTest::tri7()
418 {
419   MsqPrintError err(cout);
420   bool edge, face, vol;
421   const int num_nodes = 7;
422 
423   TopologyInfo::higher_order( TRIANGLE, num_nodes, edge, face, vol , err );
424   CPPUNIT_ASSERT(!err);
425   CPPUNIT_ASSERT( edge);
426   CPPUNIT_ASSERT( face);
427   CPPUNIT_ASSERT(!vol);
428 
429   test_face_elem( TRIANGLE, num_nodes, 3 );
430 }
431 
432 
quad()433 void TopologyInfoTest::quad()
434 {
435   MsqPrintError err(cout);
436 
437   CPPUNIT_ASSERT (2 == TopologyInfo::dimension( QUADRILATERAL ));
438   CPPUNIT_ASSERT (4 == TopologyInfo::adjacent( QUADRILATERAL, 1 ));
439   CPPUNIT_ASSERT (4 == TopologyInfo::adjacent( QUADRILATERAL, 0 ));
440   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( QUADRILATERAL, 2 ));
441   CPPUNIT_ASSERT (0 == TopologyInfo::adjacent( QUADRILATERAL, 3 ));
442 
443   CPPUNIT_ASSERT (4 == TopologyInfo::sides( QUADRILATERAL ));
444   CPPUNIT_ASSERT (4 == TopologyInfo::corners( QUADRILATERAL ));
445   CPPUNIT_ASSERT (4 == TopologyInfo::edges( QUADRILATERAL ));
446   CPPUNIT_ASSERT (1 == TopologyInfo::faces( QUADRILATERAL ));
447 
448   const unsigned num_edges = 4;
449   const unsigned* side;
450   const unsigned edges[num_edges][2] = { {0, 1}, {1, 2}, {2, 3}, {3, 0} };
451   unsigned count;
452   const unsigned face[] = { 0, 1, 2, 3 };
453 
454   for (unsigned i = 0; i < num_edges; ++i)
455   {
456     side = TopologyInfo::edge_vertices( QUADRILATERAL, i, err );
457     CPPUNIT_ASSERT(!err);
458     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
459 
460     side = TopologyInfo::side_vertices( QUADRILATERAL, 1, i, count, err );
461     CPPUNIT_ASSERT(!err);
462     CPPUNIT_ASSERT(2 == count);
463     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
464   }
465 
466   side = TopologyInfo::side_vertices( QUADRILATERAL, 2, 0, count, err );
467   CPPUNIT_ASSERT(!err);
468   CPPUNIT_ASSERT( 4 == count );
469   CPPUNIT_ASSERT( compare_face( 4, side, face ) );
470 }
471 
quad4()472 void TopologyInfoTest::quad4()
473 {
474   MsqPrintError err(cout);
475   bool edge, face, vol;
476   const int num_nodes = 4;
477 
478   TopologyInfo::higher_order( QUADRILATERAL, num_nodes, edge, face, vol , err );
479   CPPUNIT_ASSERT(!err);
480   CPPUNIT_ASSERT(!edge);
481   CPPUNIT_ASSERT(!face);
482   CPPUNIT_ASSERT(!vol);
483 
484   test_face_elem( QUADRILATERAL, num_nodes, 4 );
485 }
486 
quad5()487 void TopologyInfoTest::quad5()
488 {
489   MsqPrintError err(cout);
490   bool edge, face, vol;
491   const int num_nodes = 5;
492 
493   TopologyInfo::higher_order( QUADRILATERAL, num_nodes, edge, face, vol , err );
494   CPPUNIT_ASSERT(!err);
495   CPPUNIT_ASSERT(!edge);
496   CPPUNIT_ASSERT( face);
497   CPPUNIT_ASSERT(!vol);
498 
499   test_face_elem( QUADRILATERAL, num_nodes, 4 );
500 }
501 
quad8()502 void TopologyInfoTest::quad8()
503 {
504   MsqPrintError err(cout);
505   bool edge, face, vol;
506   const int num_nodes = 8;
507 
508   TopologyInfo::higher_order( QUADRILATERAL, num_nodes, edge, face, vol , err );
509   CPPUNIT_ASSERT(!err);
510   CPPUNIT_ASSERT( edge);
511   CPPUNIT_ASSERT(!face);
512   CPPUNIT_ASSERT(!vol);
513 
514   test_face_elem( QUADRILATERAL, num_nodes, 4 );
515 }
516 
quad9()517 void TopologyInfoTest::quad9()
518 {
519   MsqPrintError err(cout);
520   bool edge, face, vol;
521   const int num_nodes = 9;
522 
523   TopologyInfo::higher_order( QUADRILATERAL, num_nodes, edge, face, vol , err );
524   CPPUNIT_ASSERT(!err);
525   CPPUNIT_ASSERT( edge);
526   CPPUNIT_ASSERT( face);
527   CPPUNIT_ASSERT(!vol);
528 
529   test_face_elem( QUADRILATERAL, num_nodes, 4 );
530 }
531 
532 
tet()533 void TopologyInfoTest::tet()
534 {
535   MsqPrintError err(cout);
536 
537   const unsigned num_verts = 4;
538   const unsigned num_edges = 6;
539   const unsigned num_faces = 4;
540   CPPUNIT_ASSERT (3 == TopologyInfo::dimension( TETRAHEDRON ));
541   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( TETRAHEDRON, 3 ));
542   CPPUNIT_ASSERT (num_faces == TopologyInfo::adjacent( TETRAHEDRON, 2 ));
543   CPPUNIT_ASSERT (num_edges == TopologyInfo::adjacent( TETRAHEDRON, 1 ));
544   CPPUNIT_ASSERT (num_verts == TopologyInfo::adjacent( TETRAHEDRON, 0 ));
545 
546   CPPUNIT_ASSERT (num_faces == TopologyInfo::sides( TETRAHEDRON ));
547   CPPUNIT_ASSERT (num_verts == TopologyInfo::corners( TETRAHEDRON ));
548   CPPUNIT_ASSERT (num_edges == TopologyInfo::edges( TETRAHEDRON ));
549   CPPUNIT_ASSERT (num_faces == TopologyInfo::faces( TETRAHEDRON ));
550 
551   const unsigned* side;
552   unsigned i, count;
553   const unsigned vert_per_face = 3;
554   unsigned edges[num_edges][2] = { {0, 1}, {1, 2}, {2, 0},
555                                    {0, 3}, {1, 3}, {2, 3} };
556   unsigned faces[num_faces][vert_per_face] = { { 0, 1, 3 }, { 1, 2, 3 },
557                                                { 2, 0, 3 }, { 2, 1, 0 } };
558 
559   for (i = 0; i < num_edges; ++i)
560   {
561     side = TopologyInfo::edge_vertices( TETRAHEDRON, i, err );
562     CPPUNIT_ASSERT(!err);
563     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
564 
565     side = TopologyInfo::side_vertices( TETRAHEDRON, 1, i, count, err );
566     CPPUNIT_ASSERT(!err);
567     CPPUNIT_ASSERT(2 == count);
568     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
569   }
570 
571   for (i = 0; i < num_faces; ++i)
572   {
573     side = TopologyInfo::face_vertices( TETRAHEDRON, i, count, err );
574     CPPUNIT_ASSERT(!err);
575     CPPUNIT_ASSERT(count == vert_per_face);
576     CPPUNIT_ASSERT( compare_face( vert_per_face, side, faces[i] ) );
577 
578     side = TopologyInfo::side_vertices( TETRAHEDRON, 2, i, count, err );
579     CPPUNIT_ASSERT(!err);
580     CPPUNIT_ASSERT(count == vert_per_face);
581     CPPUNIT_ASSERT( compare_face( vert_per_face, side, faces[i] ) );
582   }
583 
584   side = TopologyInfo::side_vertices( TETRAHEDRON, 3, 0, count, err );
585   CPPUNIT_ASSERT(!err);
586   CPPUNIT_ASSERT(count == num_verts);
587   for (i = 0; i < num_verts; ++i)
588     CPPUNIT_ASSERT(side[i] == i);
589 }
590 
tet4()591 void TopologyInfoTest::tet4()
592 {
593   MsqPrintError err(cout);
594   bool edge, face, vol;
595   const int num_nodes = 4;
596 
597   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
598   CPPUNIT_ASSERT(!err);
599   CPPUNIT_ASSERT(!edge);
600   CPPUNIT_ASSERT(!face);
601   CPPUNIT_ASSERT(!vol);
602 
603   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
604 }
605 
tet5()606 void TopologyInfoTest::tet5()
607 {
608   MsqPrintError err(cout);
609   bool edge, face, vol;
610   const int num_nodes = 5;
611 
612   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
613   CPPUNIT_ASSERT(!err);
614   CPPUNIT_ASSERT(!edge);
615   CPPUNIT_ASSERT(!face);
616   CPPUNIT_ASSERT( vol);
617 
618   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
619 }
620 
tet8()621 void TopologyInfoTest::tet8()
622 {
623   MsqPrintError err(cout);
624   bool edge, face, vol;
625   const int num_nodes = 8;
626 
627   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
628   CPPUNIT_ASSERT(!err);
629   CPPUNIT_ASSERT(!edge);
630   CPPUNIT_ASSERT( face);
631   CPPUNIT_ASSERT(!vol);
632 
633   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
634 }
635 
tet9()636 void TopologyInfoTest::tet9()
637 {
638   MsqPrintError err(cout);
639   bool edge, face, vol;
640   const int num_nodes = 9;
641 
642   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
643   CPPUNIT_ASSERT(!err);
644   CPPUNIT_ASSERT(!edge);
645   CPPUNIT_ASSERT( face);
646   CPPUNIT_ASSERT( vol);
647 
648   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
649 }
650 
tet10()651 void TopologyInfoTest::tet10()
652 {
653   MsqPrintError err(cout);
654   bool edge, face, vol;
655   const int num_nodes = 10;
656 
657   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
658   CPPUNIT_ASSERT(!err);
659   CPPUNIT_ASSERT( edge);
660   CPPUNIT_ASSERT(!face);
661   CPPUNIT_ASSERT(!vol);
662 
663   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
664 }
665 
tet11()666 void TopologyInfoTest::tet11()
667 {
668   MsqPrintError err(cout);
669   bool edge, face, vol;
670   const int num_nodes = 11;
671 
672   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
673   CPPUNIT_ASSERT(!err);
674   CPPUNIT_ASSERT( edge);
675   CPPUNIT_ASSERT(!face);
676   CPPUNIT_ASSERT( vol);
677 
678   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
679 }
680 
tet14()681 void TopologyInfoTest::tet14()
682 {
683   MsqPrintError err(cout);
684   bool edge, face, vol;
685   const int num_nodes = 14;
686 
687   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
688   CPPUNIT_ASSERT(!err);
689   CPPUNIT_ASSERT( edge);
690   CPPUNIT_ASSERT( face);
691   CPPUNIT_ASSERT(!vol);
692 
693   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
694 }
695 
tet15()696 void TopologyInfoTest::tet15()
697 {
698   MsqPrintError err(cout);
699   bool edge, face, vol;
700   const int num_nodes = 15;
701 
702   TopologyInfo::higher_order( TETRAHEDRON, num_nodes, edge, face, vol , err );
703   CPPUNIT_ASSERT(!err);
704   CPPUNIT_ASSERT( edge);
705   CPPUNIT_ASSERT( face);
706   CPPUNIT_ASSERT( vol);
707 
708   test_vol_elem( TETRAHEDRON, num_nodes, 4, 6, 4 );
709 }
710 
711 
hex()712 void TopologyInfoTest::hex()
713 {
714   MsqPrintError err(cout);
715 
716   const unsigned num_verts = 8;
717   const unsigned num_edges = 12;
718   const unsigned num_faces = 6;
719   CPPUNIT_ASSERT (3 == TopologyInfo::dimension( HEXAHEDRON ));
720   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( HEXAHEDRON, 3 ));
721   CPPUNIT_ASSERT (num_faces == TopologyInfo::adjacent( HEXAHEDRON, 2 ));
722   CPPUNIT_ASSERT (num_edges == TopologyInfo::adjacent( HEXAHEDRON, 1 ));
723   CPPUNIT_ASSERT (num_verts == TopologyInfo::adjacent( HEXAHEDRON, 0 ));
724 
725   CPPUNIT_ASSERT (num_faces == TopologyInfo::sides( HEXAHEDRON ));
726   CPPUNIT_ASSERT (num_verts == TopologyInfo::corners( HEXAHEDRON ));
727   CPPUNIT_ASSERT (num_edges == TopologyInfo::edges( HEXAHEDRON ));
728   CPPUNIT_ASSERT (num_faces == TopologyInfo::faces( HEXAHEDRON ));
729 
730   const unsigned* side;
731   unsigned i, count;
732   const unsigned vert_per_face = 4;
733   unsigned edges[num_edges][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 },
734                                    { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 },
735                                    { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 } };
736   unsigned faces[num_faces][vert_per_face] = { { 0, 1, 5, 4 },
737                                                { 1, 2, 6, 5 },
738                                                { 2, 3, 7, 6 },
739                                                { 3, 0, 4, 7 },
740                                                { 3, 2, 1, 0 },
741                                                { 4, 5, 6, 7 } };
742 
743   for (i = 0; i < num_edges; ++i)
744   {
745     side = TopologyInfo::edge_vertices( HEXAHEDRON, i, err );
746     CPPUNIT_ASSERT(!err);
747     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
748 
749     side = TopologyInfo::side_vertices( HEXAHEDRON, 1, i, count, err );
750     CPPUNIT_ASSERT(!err);
751     CPPUNIT_ASSERT(2 == count);
752     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
753   }
754 
755   for (i = 0; i < num_faces; ++i)
756   {
757     side = TopologyInfo::face_vertices( HEXAHEDRON, i, count, err );
758     CPPUNIT_ASSERT(!err);
759     CPPUNIT_ASSERT(count == vert_per_face);
760     CPPUNIT_ASSERT( compare_face( vert_per_face, side, faces[i] ) );
761 
762     side = TopologyInfo::side_vertices( HEXAHEDRON, 2, i, count, err );
763     CPPUNIT_ASSERT(!err);
764     CPPUNIT_ASSERT(count == vert_per_face);
765     CPPUNIT_ASSERT( compare_face( vert_per_face, side, faces[i] ) );
766   }
767 
768   side = TopologyInfo::side_vertices( HEXAHEDRON, 3, 0, count, err );
769   CPPUNIT_ASSERT(!err);
770   CPPUNIT_ASSERT(count == num_verts);
771   for (i = 0; i < num_verts; ++i)
772     CPPUNIT_ASSERT(side[i] == i);
773 }
774 
hex8()775 void TopologyInfoTest:: hex8()
776 {
777   MsqPrintError err(cout);
778   bool edge, face, vol;
779   const int num_nodes = 8;
780 
781   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
782   CPPUNIT_ASSERT(!err);
783   CPPUNIT_ASSERT(!edge);
784   CPPUNIT_ASSERT(!face);
785   CPPUNIT_ASSERT(!vol);
786 
787   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
788 }
789 
hex9()790 void TopologyInfoTest:: hex9()
791 {
792   MsqPrintError err(cout);
793   bool edge, face, vol;
794   const int num_nodes = 9;
795 
796   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
797   CPPUNIT_ASSERT(!err);
798   CPPUNIT_ASSERT(!edge);
799   CPPUNIT_ASSERT(!face);
800   CPPUNIT_ASSERT( vol);
801 
802   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
803 }
804 
hex14()805 void TopologyInfoTest:: hex14()
806 {
807   MsqPrintError err(cout);
808   bool edge, face, vol;
809   const int num_nodes = 14;
810 
811   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
812   CPPUNIT_ASSERT(!err);
813   CPPUNIT_ASSERT(!edge);
814   CPPUNIT_ASSERT( face);
815   CPPUNIT_ASSERT(!vol);
816 
817   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
818 }
819 
hex15()820 void  TopologyInfoTest::hex15()
821 {
822   MsqPrintError err(cout);
823   bool edge, face, vol;
824   const int num_nodes = 15;
825 
826   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
827   CPPUNIT_ASSERT(!err);
828   CPPUNIT_ASSERT(!edge);
829   CPPUNIT_ASSERT( face);
830   CPPUNIT_ASSERT( vol);
831 
832   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
833 }
834 
hex20()835 void TopologyInfoTest:: hex20()
836 {
837   MsqPrintError err(cout);
838   bool edge, face, vol;
839   const int num_nodes = 20;
840 
841   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
842   CPPUNIT_ASSERT(!err);
843   CPPUNIT_ASSERT( edge);
844   CPPUNIT_ASSERT(!face);
845   CPPUNIT_ASSERT(!vol);
846 
847   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
848 }
849 
hex21()850 void  TopologyInfoTest::hex21()
851 {
852   MsqPrintError err(cout);
853   bool edge, face, vol;
854   const int num_nodes = 21;
855 
856   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
857   CPPUNIT_ASSERT(!err);
858   CPPUNIT_ASSERT( edge);
859   CPPUNIT_ASSERT(!face);
860   CPPUNIT_ASSERT( vol);
861 
862   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
863 }
864 
hex26()865 void  TopologyInfoTest::hex26()
866 {
867   MsqPrintError err(cout);
868   bool edge, face, vol;
869   const int num_nodes = 26;
870 
871   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
872   CPPUNIT_ASSERT(!err);
873   CPPUNIT_ASSERT( edge);
874   CPPUNIT_ASSERT( face);
875   CPPUNIT_ASSERT(!vol);
876 
877   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
878 }
879 
hex27()880 void  TopologyInfoTest::hex27()
881 {
882   MsqPrintError err(cout);
883   bool edge, face, vol;
884   const int num_nodes = 27;
885 
886   TopologyInfo::higher_order( HEXAHEDRON, num_nodes, edge, face, vol , err );
887   CPPUNIT_ASSERT(!err);
888   CPPUNIT_ASSERT( edge);
889   CPPUNIT_ASSERT( face);
890   CPPUNIT_ASSERT( vol);
891 
892   test_vol_elem( HEXAHEDRON, num_nodes, 8, 12, 6 );
893 }
894 
pyramid()895 void TopologyInfoTest::pyramid()
896 {
897   MsqPrintError err(cout);
898 
899   const unsigned num_verts = 5;
900   const unsigned num_edges = 8;
901   const unsigned num_faces = 5;
902   CPPUNIT_ASSERT (3 == TopologyInfo::dimension( PYRAMID ));
903   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( PYRAMID, 3 ));
904   CPPUNIT_ASSERT (num_faces == TopologyInfo::adjacent( PYRAMID, 2 ));
905   CPPUNIT_ASSERT (num_edges == TopologyInfo::adjacent( PYRAMID, 1 ));
906   CPPUNIT_ASSERT (num_verts == TopologyInfo::adjacent( PYRAMID, 0 ));
907 
908   CPPUNIT_ASSERT (num_faces == TopologyInfo::sides( PYRAMID ));
909   CPPUNIT_ASSERT (num_verts == TopologyInfo::corners( PYRAMID ));
910   CPPUNIT_ASSERT (num_edges == TopologyInfo::edges( PYRAMID ));
911   CPPUNIT_ASSERT (num_faces == TopologyInfo::faces( PYRAMID ));
912 
913   const unsigned* side;
914   unsigned i, count;
915   const unsigned num_tri_faces = 4;
916   const unsigned num_quad_faces = 1;
917   const bool tri_before_quad = true;
918   CPPUNIT_ASSERT( num_tri_faces + num_quad_faces == num_faces );
919   unsigned edges[num_edges][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 },
920                                    { 0, 4 }, { 1, 4 }, { 2, 4 }, { 3, 4 } };
921   unsigned tris[num_tri_faces][3] = { { 0, 1, 4 }, { 1, 2, 4 },
922                                        { 2, 3, 4 }, { 3, 0, 4 } };
923   unsigned quads[num_quad_faces][4] = { { 3, 2, 1, 0 } };
924 
925   for (i = 0; i < num_edges; ++i)
926   {
927     side = TopologyInfo::edge_vertices( PYRAMID, i, err );
928     CPPUNIT_ASSERT(!err);
929     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
930 
931     side = TopologyInfo::side_vertices( PYRAMID, 1, i, count, err );
932     CPPUNIT_ASSERT(!err);
933     CPPUNIT_ASSERT(2 == count);
934     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
935   }
936 
937   const unsigned tri_off = num_quad_faces * !tri_before_quad;
938   for (i = 0; i < num_tri_faces; ++i)
939   {
940     side = TopologyInfo::face_vertices( PYRAMID, i+tri_off, count, err );
941     CPPUNIT_ASSERT(!err);
942     CPPUNIT_ASSERT(count == 3);
943     CPPUNIT_ASSERT( compare_face( 3, side, tris[i] ) );
944 
945     side = TopologyInfo::side_vertices( PYRAMID, 2, i+tri_off, count, err );
946     CPPUNIT_ASSERT(!err);
947     CPPUNIT_ASSERT(count == 3);
948     CPPUNIT_ASSERT( compare_face( 3, side, tris[i] ) );
949   }
950 
951   const unsigned quad_off = num_tri_faces * tri_before_quad;
952   for (i = 0; i < num_quad_faces; ++i)
953   {
954     side = TopologyInfo::face_vertices( PYRAMID, i+quad_off, count, err );
955     CPPUNIT_ASSERT(!err);
956     CPPUNIT_ASSERT(count == 4);
957     CPPUNIT_ASSERT( compare_face( 4, side, quads[i] ) );
958 
959     side = TopologyInfo::side_vertices( PYRAMID, 2, i+quad_off, count, err );
960     CPPUNIT_ASSERT(!err);
961     CPPUNIT_ASSERT(count == 4);
962     CPPUNIT_ASSERT( compare_face( 4, side, quads[i] ) );
963   }
964 
965   side = TopologyInfo::side_vertices( PYRAMID, 3, 0, count, err );
966   CPPUNIT_ASSERT(!err);
967   CPPUNIT_ASSERT(count == num_verts);
968   for (i = 0; i < num_verts; ++i)
969     CPPUNIT_ASSERT(side[i] == i);
970 }
971 
pyramid5()972 void TopologyInfoTest::pyramid5()
973 {
974   MsqPrintError err(cout);
975   bool edge, face, vol;
976   const int num_nodes = 5;
977 
978   TopologyInfo::higher_order( PYRAMID, num_nodes, edge, face, vol , err );
979   CPPUNIT_ASSERT(!err);
980   CPPUNIT_ASSERT(!edge);
981   CPPUNIT_ASSERT(!face);
982   CPPUNIT_ASSERT(!vol);
983 
984   test_vol_elem( PYRAMID, num_nodes, 5, 8, 5 );
985 }
986 
pyramid13()987 void TopologyInfoTest::pyramid13()
988 {
989   MsqPrintError err(cout);
990   bool edge, face, vol;
991   const int num_nodes = 13;
992 
993   TopologyInfo::higher_order( PYRAMID, num_nodes, edge, face, vol , err );
994   CPPUNIT_ASSERT(!err);
995   CPPUNIT_ASSERT( edge);
996   CPPUNIT_ASSERT(!face);
997   CPPUNIT_ASSERT(!vol);
998 
999   test_vol_elem( PYRAMID, num_nodes, 5, 8, 5 );
1000 }
1001 
wedge()1002 void TopologyInfoTest::wedge()
1003 {
1004   MsqPrintError err(cout);
1005 
1006   const unsigned num_verts = 6;
1007   const unsigned num_edges = 9;
1008   const unsigned num_faces = 5;
1009   CPPUNIT_ASSERT (3 == TopologyInfo::dimension( PRISM ));
1010   CPPUNIT_ASSERT (1 == TopologyInfo::adjacent( PRISM, 3 ));
1011   CPPUNIT_ASSERT (num_faces == TopologyInfo::adjacent( PRISM, 2 ));
1012   CPPUNIT_ASSERT (num_edges == TopologyInfo::adjacent( PRISM, 1 ));
1013   CPPUNIT_ASSERT (num_verts == TopologyInfo::adjacent( PRISM, 0 ));
1014 
1015   CPPUNIT_ASSERT (num_faces == TopologyInfo::sides( PRISM ));
1016   CPPUNIT_ASSERT (num_verts == TopologyInfo::corners( PRISM ));
1017   CPPUNIT_ASSERT (num_edges == TopologyInfo::edges( PRISM ));
1018   CPPUNIT_ASSERT (num_faces == TopologyInfo::faces( PRISM ));
1019 
1020   const unsigned* side;
1021   unsigned i, count;
1022   const unsigned num_tri_faces = 2;
1023   const unsigned num_quad_faces = 3;
1024   const bool tri_before_quad = false;
1025   CPPUNIT_ASSERT( num_tri_faces + num_quad_faces == num_faces );
1026   unsigned edges[num_edges][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 },
1027                                    { 0, 3 }, { 1, 4 }, { 2, 5 },
1028                                    { 3, 4 }, { 4, 5 }, { 5, 3 } };
1029   unsigned tris[num_tri_faces][3] = { { 2, 1, 0 }, { 3, 4, 5 } };
1030   unsigned quads[num_quad_faces][4] = { { 0, 1, 4, 3 },
1031                                         { 1, 2, 5, 4 },
1032                                         { 2, 0, 3, 5 } };
1033 
1034   for (i = 0; i < num_edges; ++i)
1035   {
1036     side = TopologyInfo::edge_vertices( PRISM, i, err );
1037     CPPUNIT_ASSERT(!err);
1038     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
1039 
1040     side = TopologyInfo::side_vertices( PRISM, 1, i, count, err );
1041     CPPUNIT_ASSERT(!err);
1042     CPPUNIT_ASSERT(2 == count);
1043     CPPUNIT_ASSERT( compare_edge( side, edges[i] ) );
1044   }
1045 
1046   const unsigned tri_off = num_quad_faces * !tri_before_quad;
1047   for (i = 0; i < num_tri_faces; ++i)
1048   {
1049     side = TopologyInfo::face_vertices( PRISM, i+tri_off, count, err );
1050     CPPUNIT_ASSERT(!err);
1051     CPPUNIT_ASSERT(count == 3);
1052     CPPUNIT_ASSERT( compare_face( 3, side, tris[i] ) );
1053 
1054     side = TopologyInfo::side_vertices( PRISM, 2, i+tri_off, count, err );
1055     CPPUNIT_ASSERT(!err);
1056     CPPUNIT_ASSERT(count == 3);
1057     CPPUNIT_ASSERT( compare_face( 3, side, tris[i] ) );
1058   }
1059 
1060   const unsigned quad_off = num_tri_faces * tri_before_quad;
1061   for (i = 0; i < num_quad_faces; ++i)
1062   {
1063     side = TopologyInfo::face_vertices( PRISM, i+quad_off, count, err );
1064     CPPUNIT_ASSERT(!err);
1065     CPPUNIT_ASSERT(count == 4);
1066     CPPUNIT_ASSERT( compare_face( 4, side, quads[i] ) );
1067 
1068     side = TopologyInfo::side_vertices( PRISM, 2, i+quad_off, count, err );
1069     CPPUNIT_ASSERT(!err);
1070     CPPUNIT_ASSERT(count == 4);
1071     CPPUNIT_ASSERT( compare_face( 4, side, quads[i] ) );
1072   }
1073 
1074   side = TopologyInfo::side_vertices( PRISM, 3, 0, count, err );
1075   CPPUNIT_ASSERT(!err);
1076   CPPUNIT_ASSERT(count == num_verts);
1077   for (i = 0; i < num_verts; ++i)
1078     CPPUNIT_ASSERT(side[i] == i);
1079 }
1080 
wedge6()1081 void TopologyInfoTest::wedge6()
1082 {
1083   MsqPrintError err(cout);
1084   bool edge, face, vol;
1085   const int num_nodes = 6;
1086 
1087   TopologyInfo::higher_order( PRISM, num_nodes, edge, face, vol , err );
1088   CPPUNIT_ASSERT(!err);
1089   CPPUNIT_ASSERT(!edge);
1090   CPPUNIT_ASSERT(!face);
1091   CPPUNIT_ASSERT(!vol);
1092 
1093   test_vol_elem( PRISM, num_nodes, 6, 9, 5 );
1094 }
1095 
wedge15()1096 void TopologyInfoTest::wedge15()
1097 {
1098   MsqPrintError err(cout);
1099   bool edge, face, vol;
1100   const int num_nodes = 15;
1101 
1102   TopologyInfo::higher_order( PRISM, num_nodes, edge, face, vol , err );
1103   CPPUNIT_ASSERT(!err);
1104   CPPUNIT_ASSERT( edge);
1105   CPPUNIT_ASSERT(!face);
1106   CPPUNIT_ASSERT(!vol);
1107 
1108   test_vol_elem( PRISM, num_nodes, 6, 9, 5 );
1109 }
1110 
test_poly(EntityTopology topo)1111 void TopologyInfoTest::test_poly( EntityTopology topo )
1112 {
1113   CPPUNIT_ASSERT( TopologyInfo::adjacent(topo, 1) == 0 );
1114   CPPUNIT_ASSERT( TopologyInfo::sides(topo) == 0 );
1115   CPPUNIT_ASSERT( TopologyInfo::corners(topo) == 0 );
1116   CPPUNIT_ASSERT( TopologyInfo::edges(topo) == 0 );
1117   CPPUNIT_ASSERT( TopologyInfo::faces(topo) == 0 );
1118 }
1119 
1120 
polygon()1121 void TopologyInfoTest::polygon()
1122 {
1123   CPPUNIT_ASSERT( TopologyInfo::dimension( POLYGON ) == 2 );
1124   test_poly( POLYGON );
1125 }
1126 
polyhedron()1127 void TopologyInfoTest::polyhedron()
1128 {
1129   CPPUNIT_ASSERT( TopologyInfo::dimension( POLYHEDRON ) == 3 );
1130   test_poly( POLYHEDRON );
1131 }
1132 
1133 
bad_type()1134 void TopologyInfoTest::bad_type()
1135 {
1136   MBMesquite::MsqError err;
1137   EntityTopology bad_types[] = { (EntityTopology)0,
1138                                  (EntityTopology)1,
1139                                  MIXED,
1140                                  (EntityTopology)(MIXED + 1)
1141                                };
1142 
1143   for (unsigned i = 0; i < (sizeof(bad_types)/sizeof(EntityTopology)); ++i)
1144   {
1145     CPPUNIT_ASSERT( TopologyInfo::dimension(bad_types[i]) == 0 );
1146     CPPUNIT_ASSERT( TopologyInfo::adjacent(bad_types[i], 1) == 0 );
1147     CPPUNIT_ASSERT( TopologyInfo::sides(bad_types[i]) == 0 );
1148     CPPUNIT_ASSERT( TopologyInfo::corners(bad_types[i]) == 0 );
1149     CPPUNIT_ASSERT( TopologyInfo::edges(bad_types[i]) == 0 );
1150     CPPUNIT_ASSERT( TopologyInfo::faces(bad_types[i]) == 0 );
1151 
1152     bool a,b, c;
1153     TopologyInfo::higher_order( bad_types[i], 20, a, b, c, err );
1154     CPPUNIT_ASSERT(err);
1155 
1156     const unsigned* ptr;
1157     ptr = TopologyInfo::edge_vertices( bad_types[i], 0, err );
1158     CPPUNIT_ASSERT(err);
1159 
1160     unsigned count;
1161     ptr = TopologyInfo::face_vertices( bad_types[i], 0, count, err );
1162     CPPUNIT_ASSERT(err);
1163 
1164     for (unsigned j = 0; j < 4; ++j)
1165     {
1166       ptr = TopologyInfo::side_vertices( bad_types[i], j, 0, count, err );
1167       CPPUNIT_ASSERT(err);
1168     }
1169 
1170     unsigned dim, side;
1171     for (unsigned idx = 0; idx < 20; ++idx)
1172     {
1173       TopologyInfo::side_number( bad_types[i], idx, idx/2, dim, side, err );
1174       CPPUNIT_ASSERT(err);
1175     }
1176   }
1177 }
1178 
1179 
tri_adj_vert()1180 void TopologyInfoTest::tri_adj_vert()
1181 {
1182   unsigned data[][5] = { { 2, 1, 2, 0, 0 },
1183                          { 2, 2, 0, 0, 0 },
1184                          { 2, 0, 1, 0, 0 } };
1185   test_adj( MBMesquite::TRIANGLE, data );
1186 }
1187 
quad_adj_vert()1188 void TopologyInfoTest::quad_adj_vert()
1189 {
1190   unsigned data[][5] = { { 2, 1, 3, 0, 0 },
1191                          { 2, 2, 0, 0, 0 },
1192                          { 2, 3, 1, 0, 0 },
1193                          { 2, 0, 2, 0, 0 } };
1194   test_adj( MBMesquite::QUADRILATERAL, data );
1195 }
1196 
tet_adj_vert()1197 void TopologyInfoTest::tet_adj_vert()
1198 {
1199   unsigned data[][5] = { { 3, 1, 2, 3, 0 },
1200                          { 3, 2, 0, 3, 0 },
1201                          { 3, 0, 1, 3, 0 },
1202                          { 3, 2, 1, 0, 0 } };
1203   test_adj( MBMesquite::TETRAHEDRON, data );
1204 }
1205 
hex_adj_vert()1206 void TopologyInfoTest::hex_adj_vert()
1207 {
1208   unsigned data[][5] = { { 3, 1, 3, 4, 0 },
1209                          { 3, 2, 0, 5, 0 },
1210                          { 3, 3, 1, 6, 0 },
1211                          { 3, 0, 2, 7, 0 },
1212                          { 3, 7, 5, 0, 0 },
1213                          { 3, 4, 6, 1, 0 },
1214                          { 3, 5, 7, 2, 0 },
1215                          { 3, 6, 4, 3, 0 } };
1216   test_adj( MBMesquite::HEXAHEDRON, data );
1217 }
1218 
pyr_adj_vert()1219 void TopologyInfoTest::pyr_adj_vert()
1220 {
1221   unsigned data[][5] = { { 3, 1, 3, 4, 0 },
1222                          { 3, 2, 0, 4, 0 },
1223                          { 3, 3, 1, 4, 0 },
1224                          { 3, 0, 2, 4, 0 },
1225                          { 4, 3, 2, 1, 0 } };
1226   test_adj( MBMesquite::PYRAMID, data );
1227 }
1228 
wdg_adj_vert()1229 void TopologyInfoTest::wdg_adj_vert()
1230 {
1231   unsigned data[][5] = { { 3, 1, 2, 3, 0 },
1232                          { 3, 2, 0, 4, 0 },
1233                          { 3, 0, 1, 5, 0 },
1234                          { 3, 5, 4, 0, 0 },
1235                          { 3, 3, 5, 1, 0 },
1236                          { 3, 4, 3, 2, 0 } };
1237   test_adj( MBMesquite::PRISM, data );
1238 }
1239 
test_adj(MBMesquite::EntityTopology type,const unsigned data[][5])1240 void TopologyInfoTest::test_adj( MBMesquite::EntityTopology type,
1241                                  const unsigned data[][5] )
1242 {
1243     // Get num vertices from type
1244   unsigned n = TopologyInfo::corners( type );
1245   CPPUNIT_ASSERT( n > 0 );
1246 
1247   // The first index into data is the vertex.
1248   // Each column of "data", indexed by vertex, is a
1249   // vector containing the number of adjacent vertices
1250   // followed by the list if adjacent vertex indices.
1251 
1252     // for each vertex
1253   for (unsigned i = 0; i < n; ++i)
1254   {
1255       // Get the data corresponding to this vertex of the element
1256     unsigned const * corner = data[i];
1257     unsigned expected_count = corner[0];
1258       // Query TopologyInfo for the same data
1259     unsigned actual_count;
1260     unsigned const* actual_adj = TopologyInfo::adjacent_vertices( type, i, actual_count );
1261       // Check result is valid and counts match
1262     CPPUNIT_ASSERT( actual_adj != NULL );
1263     CPPUNIT_ASSERT( expected_count == actual_count );
1264 
1265       // For 3-D elements, returned vertices are expected to be oriented
1266       // such that  a face bounded by the vertices in the counter-clockwise
1267       // order will have a normal pointing away from the input vertex.
1268       // So the vertices must be in a certain order, but may begin with
1269       // any of the adjacent vertices.
1270 
1271       // Find the location in the result list at which the first
1272       // vertex in the expected list occurs.
1273     unsigned j;
1274     for (j = 0; j < actual_count; ++j)
1275       if (corner[1] == actual_adj[j])
1276         break;
1277       // Asssert that the first expected vertex was somewhere in
1278       // the result list.
1279     CPPUNIT_ASSERT( j < actual_count );
1280       // Compare the remaining vertices, enforcing the order.
1281     for (unsigned k = 1; k < actual_count; ++k)
1282       CPPUNIT_ASSERT( corner[k+1] == actual_adj[(k+j)%actual_count] );
1283   }
1284 }
1285 
test_rev_adj(MBMesquite::EntityTopology type)1286 void TopologyInfoTest::test_rev_adj( MBMesquite::EntityTopology type )
1287 {
1288     // Get num vertices from type
1289   unsigned n = TopologyInfo::corners( type );
1290   CPPUNIT_ASSERT( n > 0 );
1291 
1292     // for each vertex
1293   for (unsigned i = 0; i < n; ++i)
1294   {
1295       // get adjacent vertex list
1296     unsigned num_adj_idx;
1297     unsigned const* adj_idx = TopologyInfo::adjacent_vertices( type, i, num_adj_idx );
1298     CPPUNIT_ASSERT( adj_idx != NULL );
1299     CPPUNIT_ASSERT( num_adj_idx > 1 );
1300 
1301       // make sure adjacent vertex list is unique
1302     std::vector<unsigned> adj_idx_copy( num_adj_idx );
1303     std::copy( adj_idx, adj_idx+num_adj_idx, adj_idx_copy.begin() );
1304     std::sort( adj_idx_copy.begin(), adj_idx_copy.end() );
1305     std::vector<unsigned>::iterator iter;
1306     iter = std::unique( adj_idx_copy.begin(), adj_idx_copy.end() );
1307     CPPUNIT_ASSERT( iter == adj_idx_copy.end() );
1308 
1309       // Get reverse mapping indices
1310     unsigned num_rev_idx;
1311     unsigned const* rev_idx
1312      = TopologyInfo::reverse_vertex_adjacency_offsets( type, i, num_rev_idx );
1313     CPPUNIT_ASSERT( rev_idx != NULL );
1314     CPPUNIT_ASSERT( num_rev_idx == num_adj_idx );
1315 
1316       // for each adjacent vertex, test reverse mapping
1317     for (unsigned j = 0; j < num_adj_idx; ++j)
1318     {
1319       unsigned num_adj_adj_idx;
1320       unsigned const* adj_adj_idx
1321         = TopologyInfo::adjacent_vertices( type, adj_idx[j], num_adj_adj_idx );
1322 
1323       CPPUNIT_ASSERT( rev_idx[j] < num_adj_adj_idx );
1324       CPPUNIT_ASSERT( adj_adj_idx[rev_idx[j]] == i );
1325     }
1326   }
1327 }
1328 
1329 
1330 struct ho_result { unsigned dim; unsigned num; unsigned idx; };
1331 
1332 const ho_result HEX27[] = {
1333     { 1,  0,  8 },
1334     { 1,  1,  9 },
1335     { 1,  2, 10 },
1336     { 1,  3, 11 },
1337     { 1,  4, 12 },
1338     { 1,  5, 13 },
1339     { 1,  6, 14 },
1340     { 1,  7, 15 },
1341     { 1,  8, 16 },
1342     { 1,  9, 17 },
1343     { 1, 10, 18 },
1344     { 1, 11, 19 },
1345     { 2,  0, 20 },
1346     { 2,  1, 21 },
1347     { 2,  2, 22 },
1348     { 2,  3, 23 },
1349     { 2,  4, 24 },
1350     { 2,  5, 25 },
1351     { 3,  0, 26 } };
1352 
1353 const ho_result* const HEX20 = HEX27;
1354 const ho_result* const HEX26 = HEX27;
1355 
1356 const ho_result HEX15[] = {
1357   { 2, 0,  8 },
1358   { 2, 1,  9 },
1359   { 2, 2, 10 },
1360   { 2, 3, 11 },
1361   { 2, 4, 12 },
1362   { 2, 5, 13 },
1363   { 3, 0, 14 } };
1364 
1365 const ho_result* const HEX14 = HEX15;
1366 
1367 const ho_result HEX9[] = { { 3, 0, 8 } };
1368 
higher_order_from_side()1369 void TopologyInfoTest::higher_order_from_side()
1370 {
1371   MsqPrintError err(std::cerr);
1372     // HEX-27
1373   for (unsigned i = 0; i < 19; ++i) {
1374     unsigned result = TopologyInfo::higher_order_from_side(
1375                          HEXAHEDRON,
1376                          27,
1377                          HEX27[i].dim,
1378                          HEX27[i].num,
1379                          err );
1380     CPPUNIT_ASSERT( !err );
1381     CPPUNIT_ASSERT_EQUAL( HEX27[i].idx, result );
1382   }
1383     // HEX-26
1384   for (unsigned i = 0; i < 18; ++i) {
1385     unsigned result = TopologyInfo::higher_order_from_side(
1386                          HEXAHEDRON,
1387                          26,
1388                          HEX26[i].dim,
1389                          HEX26[i].num,
1390                          err );
1391     CPPUNIT_ASSERT( !err );
1392     CPPUNIT_ASSERT_EQUAL( HEX26[i].idx, result );
1393   }
1394     // HEX-20
1395   for (unsigned i = 0; i < 12; ++i) {
1396     unsigned result = TopologyInfo::higher_order_from_side(
1397                          HEXAHEDRON,
1398                          20,
1399                          HEX20[i].dim,
1400                          HEX20[i].num,
1401                          err );
1402     CPPUNIT_ASSERT( !err );
1403     CPPUNIT_ASSERT_EQUAL( HEX20[i].idx, result );
1404   }
1405     // HEX-15
1406   for (unsigned i = 0; i < 7; ++i) {
1407     unsigned result = TopologyInfo::higher_order_from_side(
1408                          HEXAHEDRON,
1409                          15,
1410                          HEX15[i].dim,
1411                          HEX15[i].num,
1412                          err );
1413     CPPUNIT_ASSERT( !err );
1414     CPPUNIT_ASSERT_EQUAL( HEX15[i].idx, result );
1415   }
1416     // HEX-14
1417   for (unsigned i = 0; i < 6; ++i) {
1418     unsigned result = TopologyInfo::higher_order_from_side(
1419                          HEXAHEDRON,
1420                          14,
1421                          HEX14[i].dim,
1422                          HEX14[i].num,
1423                          err );
1424     CPPUNIT_ASSERT( !err );
1425     CPPUNIT_ASSERT_EQUAL( HEX14[i].idx, result );
1426   }
1427     // HEX-9
1428   for (unsigned i = 0; i < 1; ++i) {
1429     unsigned result = TopologyInfo::higher_order_from_side(
1430                          HEXAHEDRON,
1431                          9,
1432                          HEX9[i].dim,
1433                          HEX9[i].num,
1434                          err );
1435     CPPUNIT_ASSERT( !err );
1436     CPPUNIT_ASSERT_EQUAL( HEX9[i].idx, result );
1437   }
1438 }
1439 
side_from_higher_order()1440 void TopologyInfoTest::side_from_higher_order()
1441 {
1442   MsqPrintError err(std::cerr);
1443   unsigned dim, num;
1444     // HEX-27
1445   for (unsigned i = 0; i < 19; ++i) {
1446     TopologyInfo::side_from_higher_order( HEXAHEDRON, 27, HEX27[i].idx, dim, num, err );
1447     CPPUNIT_ASSERT( !err );
1448     CPPUNIT_ASSERT_EQUAL( HEX27[i].dim, dim );
1449     CPPUNIT_ASSERT_EQUAL( HEX27[i].num, num );
1450   }
1451     // HEX-26
1452   for (unsigned i = 0; i < 18; ++i) {
1453     TopologyInfo::side_from_higher_order( HEXAHEDRON, 26, HEX26[i].idx, dim, num, err );
1454     CPPUNIT_ASSERT( !err );
1455     CPPUNIT_ASSERT_EQUAL( HEX26[i].dim, dim );
1456     CPPUNIT_ASSERT_EQUAL( HEX26[i].num, num );
1457   }
1458     // HEX-20
1459   for (unsigned i = 0; i < 12; ++i) {
1460     TopologyInfo::side_from_higher_order( HEXAHEDRON, 20, HEX20[i].idx, dim, num, err );
1461     CPPUNIT_ASSERT( !err );
1462     CPPUNIT_ASSERT_EQUAL( HEX20[i].dim, dim );
1463     CPPUNIT_ASSERT_EQUAL( HEX20[i].num, num );
1464   }
1465     // HEX-15
1466   for (unsigned i = 0; i < 7; ++i) {
1467     TopologyInfo::side_from_higher_order( HEXAHEDRON, 15, HEX15[i].idx, dim, num, err );
1468     CPPUNIT_ASSERT( !err );
1469     CPPUNIT_ASSERT_EQUAL( HEX15[i].dim, dim );
1470     CPPUNIT_ASSERT_EQUAL( HEX15[i].num, num );
1471   }
1472     // HEX-14
1473   for (unsigned i = 0; i < 6; ++i) {
1474     TopologyInfo::side_from_higher_order( HEXAHEDRON, 14, HEX14[i].idx, dim, num, err );
1475     CPPUNIT_ASSERT( !err );
1476     CPPUNIT_ASSERT_EQUAL( HEX14[i].dim, dim );
1477     CPPUNIT_ASSERT_EQUAL( HEX14[i].num, num );
1478   }
1479     // HEX-9
1480   for (unsigned i = 0; i < 1; ++i) {
1481     TopologyInfo::side_from_higher_order( HEXAHEDRON, 9, HEX9[i].idx, dim, num, err );
1482     CPPUNIT_ASSERT( !err );
1483     CPPUNIT_ASSERT_EQUAL( HEX9[i].dim, dim );
1484     CPPUNIT_ASSERT_EQUAL( HEX9[i].num, num );
1485   }
1486 }
1487 
1488 
1489 
1490 
find_edge()1491 void TopologyInfoTest::find_edge()
1492 {
1493   MsqPrintError err(std::cerr);
1494   bool reversed;
1495 
1496   EntityTopology types[] = { TRIANGLE, QUADRILATERAL, TETRAHEDRON, HEXAHEDRON, PRISM, PYRAMID };
1497   const unsigned num_types = sizeof(types)/sizeof(types[0]);
1498   unsigned idx;
1499   for (unsigned t = 0; t < num_types; ++t) {
1500     const EntityTopology type = types[t];
1501 
1502     for (unsigned e = 0; e < TopologyInfo::edges(type); ++e) {
1503 
1504       const unsigned *const v = TopologyInfo::edge_vertices( type, e, err );
1505       CPPUNIT_ASSERT(!err);
1506       idx = TopologyInfo::find_edge( type, v, reversed, err );
1507       CPPUNIT_ASSERT(!err);
1508       CPPUNIT_ASSERT_EQUAL( e, idx );
1509       CPPUNIT_ASSERT( !reversed );
1510 
1511       const unsigned switched[2] = { v[1], v[0] };
1512       idx = TopologyInfo::find_edge( type, switched, reversed, err );
1513       CPPUNIT_ASSERT(!err);
1514       CPPUNIT_ASSERT_EQUAL( e, idx );
1515       CPPUNIT_ASSERT( reversed );
1516     }
1517   }
1518 }
1519 
shift(const unsigned * in,unsigned * out,unsigned size,unsigned offset)1520 static void shift( const unsigned* in, unsigned* out, unsigned size, unsigned offset )
1521 {
1522   for (unsigned i = 0; i < size; ++i)
1523     out[i] = in[(i+offset)%size];
1524 }
1525 
reverse(const unsigned * in,unsigned * out,unsigned size,unsigned offset)1526 static void reverse( const unsigned* in, unsigned* out, unsigned size, unsigned offset )
1527 {
1528   for (unsigned i = 0; i < size; ++i)
1529     out[i] = in[(offset + size - i - 1)%size];
1530 }
1531 
find_face()1532 void TopologyInfoTest::find_face()
1533 {
1534   MsqPrintError err(std::cerr);
1535   bool reversed;
1536   unsigned switched[4], idx;
1537 
1538   EntityTopology types[] = { TETRAHEDRON, HEXAHEDRON, PRISM, PYRAMID };
1539   const unsigned num_types = sizeof(types)/sizeof(types[0]);
1540   for (unsigned t = 0; t < num_types; ++t) {
1541     const EntityTopology type = types[t];
1542 
1543     for (unsigned f = 0; f < TopologyInfo::faces(type); ++f) {
1544 
1545       unsigned n;
1546       const unsigned *const v = TopologyInfo::face_vertices( type, f, n, err );
1547       CPPUNIT_ASSERT(!err);
1548       CPPUNIT_ASSERT(n == 3 || n == 4);
1549 
1550       idx = TopologyInfo::find_face( type, v, n, reversed, err );
1551       CPPUNIT_ASSERT(!err);
1552       CPPUNIT_ASSERT_EQUAL( f, idx );
1553       CPPUNIT_ASSERT( !reversed );
1554 
1555       // advance by 1 and try again
1556       shift( v, switched, n, 1 );
1557       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1558       CPPUNIT_ASSERT(!err);
1559       CPPUNIT_ASSERT_EQUAL( f, idx );
1560       CPPUNIT_ASSERT( !reversed );
1561 
1562       // advance by 2 and try again
1563       shift( v, switched, n, 2 );
1564       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1565       CPPUNIT_ASSERT(!err);
1566       CPPUNIT_ASSERT_EQUAL( f, idx );
1567       CPPUNIT_ASSERT( !reversed );
1568 
1569       // advance by 3 and try again
1570       shift( v, switched, n, 3 );
1571       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1572       CPPUNIT_ASSERT(!err);
1573       CPPUNIT_ASSERT_EQUAL( f, idx );
1574       CPPUNIT_ASSERT( !reversed );
1575 
1576       // reverse and try again
1577       reverse( v, switched, n, 0 );
1578       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1579       CPPUNIT_ASSERT(!err);
1580       CPPUNIT_ASSERT_EQUAL( f, idx );
1581       CPPUNIT_ASSERT( reversed );
1582 
1583       // reverse, advance by 1 and try again
1584       reverse( v, switched, n, 1 );
1585       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1586       CPPUNIT_ASSERT(!err);
1587       CPPUNIT_ASSERT_EQUAL( f, idx );
1588       CPPUNIT_ASSERT( reversed );
1589 
1590       // reverse, advance by 2 and try again
1591       reverse( v, switched, n, 2 );
1592       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1593       CPPUNIT_ASSERT(!err);
1594       CPPUNIT_ASSERT_EQUAL( f, idx );
1595       CPPUNIT_ASSERT( reversed );
1596 
1597       // reverse, advance by 3 and try again
1598       reverse( v, switched, n, 3 );
1599       idx = TopologyInfo::find_face( type, switched, n, reversed, err );
1600       CPPUNIT_ASSERT(!err);
1601       CPPUNIT_ASSERT_EQUAL( f, idx );
1602       CPPUNIT_ASSERT( reversed );
1603     }
1604   }
1605 }
1606 
1607 
find_side()1608 void TopologyInfoTest::find_side()
1609 {
1610   MsqPrintError err(std::cerr);
1611   bool reversed;
1612   unsigned i, dim, switched[4];
1613 
1614   EntityTopology types[] = { TRIANGLE, QUADRILATERAL, TETRAHEDRON, HEXAHEDRON, PRISM, PYRAMID };
1615   const unsigned num_types = sizeof(types)/sizeof(types[0]);
1616   for (unsigned t = 0; t < num_types; ++t) {
1617     const EntityTopology type = types[t];
1618 
1619     for (unsigned e = 0; e < TopologyInfo::edges(type); ++e) {
1620 
1621       const unsigned *const v = TopologyInfo::edge_vertices( type, e, err );
1622       CPPUNIT_ASSERT(!err);
1623       TopologyInfo::find_side( type, v, 2, dim, i, reversed, err );
1624       CPPUNIT_ASSERT(!err);
1625       CPPUNIT_ASSERT_EQUAL( e, i );
1626       CPPUNIT_ASSERT_EQUAL( 1u, dim );
1627       CPPUNIT_ASSERT( !reversed );
1628 
1629       switched[0] = v[1]; switched[1] = v[0];
1630       TopologyInfo::find_side( type, switched, 2, dim, i, reversed, err );
1631       CPPUNIT_ASSERT(!err);
1632       CPPUNIT_ASSERT_EQUAL( e, i );
1633       CPPUNIT_ASSERT_EQUAL( 1u, dim );
1634       CPPUNIT_ASSERT( reversed );
1635     }
1636   }
1637 
1638   for (unsigned t = 2; t < num_types; ++t) {
1639     const EntityTopology type = types[t];
1640 
1641     for (unsigned f = 0; f < TopologyInfo::faces(type); ++f) {
1642 
1643       unsigned n;
1644       const unsigned *const v = TopologyInfo::face_vertices( type, f, n, err );
1645       CPPUNIT_ASSERT(!err);
1646       CPPUNIT_ASSERT(n == 3 || n == 4);
1647 
1648       TopologyInfo::find_side( type, v, n, dim, i, reversed, err );
1649       CPPUNIT_ASSERT(!err);
1650       CPPUNIT_ASSERT_EQUAL( f, i );
1651       CPPUNIT_ASSERT_EQUAL( 2u, dim );
1652       CPPUNIT_ASSERT( !reversed );
1653 
1654       // reverse and try again
1655       reverse( v, switched, n, 0 );
1656       TopologyInfo::find_side( type, switched, n, dim, i, reversed, err );
1657       CPPUNIT_ASSERT(!err);
1658       CPPUNIT_ASSERT_EQUAL( f, i );
1659       CPPUNIT_ASSERT_EQUAL( 2u, dim );
1660       CPPUNIT_ASSERT( reversed );
1661     }
1662   }
1663 }
1664 
compare_sides()1665 void TopologyInfoTest::compare_sides()
1666 {
1667   // define two hexes sharing a face:
1668 //    6-------7-------8
1669 //   /|      /|      /|
1670 //  0-------1-------2 |
1671 //  | |     | |     | |
1672 //  | 9-----|-10----|-11
1673 //  |/      |/      |/
1674 //  3-------4-------5
1675 
1676   const size_t hex1[] = { 3, 4, 10, 9, 0, 1, 7, 6 };
1677   const size_t hex2[] = { 4, 5, 11, 10, 1, 2, 8, 7 };
1678     // shared edges: { hex1_edge, hex2_edge }
1679   const unsigned edges[][2] = { { 1, 3 },
1680                                 { 5, 4 },
1681                                 { 6, 7 },
1682                                 { 9, 11} };
1683   const unsigned num_edges = sizeof(edges)/sizeof(edges[0]);
1684     // shared faces: { hex1_face, hex2_face }
1685   const unsigned faces[][2] = { { 1, 3 } };
1686   const unsigned num_faces = sizeof(faces)/sizeof(faces[0]);
1687 
1688   MsqPrintError err(std::cerr);
1689 
1690     // try every possible edge combination
1691   for (unsigned e1 = 0; e1 < 12; ++e1) {
1692     unsigned match;
1693     for (match = 0; match < num_edges; ++match)
1694       if (edges[match][0] == e1)
1695         break;
1696 
1697     for (unsigned e2 = 0; e2 < 12; ++e2) {
1698       const bool expected = (match < num_edges) && (edges[match][1] == e2);
1699 
1700       const bool result = TopologyInfo::compare_sides( hex1, HEXAHEDRON, e1,
1701                                                        hex2, HEXAHEDRON, e2,
1702                                                        1, err );
1703 
1704       CPPUNIT_ASSERT(!err);
1705       CPPUNIT_ASSERT_EQUAL( expected, result );
1706     }
1707   }
1708 
1709     // try every possible face combination
1710   for (unsigned f1 = 0; f1 < 6; ++f1) {
1711     unsigned match;
1712     for (match = 0; match < num_faces; ++match)
1713       if (faces[match][0] == f1)
1714         break;
1715 
1716     for (unsigned f2 = 0; f2 < 6; ++f2) {
1717       const bool expected = (match < num_faces) && (faces[match][1] == f2);
1718 
1719       const bool result = TopologyInfo::compare_sides( hex1, HEXAHEDRON, f1,
1720                                                        hex2, HEXAHEDRON, f2,
1721                                                        2, err );
1722 
1723       CPPUNIT_ASSERT(!err);
1724       CPPUNIT_ASSERT_EQUAL( expected, result );
1725     }
1726   }
1727 }
1728