1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /****************************************************************************/
4 /*                                                                          */
5 /* File:      rm.c                                                          */
6 /*                                                                          */
7 /* Purpose:   rule manager for 2D and 3D refinement rules                   */
8 /*                                                                          */
9 /* Author:    Stefan Lang                                                   */
10 /*            Institut fuer Computeranwendungen III                         */
11 /*            Universitaet Stuttgart                                        */
12 /*            Pfaffenwaldring 27                                            */
13 /*            70550 Stuttgart                                               */
14 /*                                                                          */
15 /* History:   21.11.95 begin, ugp version 3.0                               */
16 /*                                                                          */
17 /* Remarks:                                                                 */
18 /*                                                                          */
19 /****************************************************************************/
20 
21 /****************************************************************************/
22 /*                                                                          */
23 /* include files                                                            */
24 /* system include files                                                     */
25 /* application include files                                                */
26 /*                                                                          */
27 /****************************************************************************/
28 
29 #include <config.h>
30 
31 /* standard C library */
32 #include <cassert>
33 #include <cstdio>
34 #include <cmath>
35 #include <cstdlib>
36 
37 /* low module */
38 #include <dune/uggrid/low/architecture.h>
39 #include <dune/uggrid/low/debug.h>
40 #include <dune/uggrid/low/fileopen.h>
41 #include <dune/uggrid/low/misc.h>
42 
43 /* dev module */
44 #include <dune/uggrid/ugdevices.h>
45 
46 /* gm module */
47 #include "evm.h"
48 #include "gm.h"
49 #include "refine.h"
50 #include "shapes.h"
51 #include "rm.h"
52 #include "cw.h"
53 #include "elements.h"
54 
55 #ifdef ModelP
56 #include <dune/uggrid/parallel/dddif/parallel.h>
57 using namespace PPIF;
58 #endif
59 
60 USING_UG_NAMESPACES
61 
62 /****************************************************************************/
63 /*																			*/
64 /* defines in the following order											*/
65 /*																			*/
66 /*		  compile time constants defining static data size (i.e. arrays)	*/
67 /*		  other constants													*/
68 /*		  macros															*/
69 /*																			*/
70 /****************************************************************************/
71 
72 /* macros defining best refrule, specify exactly one of them !! */
73 /*#define __SHORTEST_INTERIOR_EDGE__*/
74 /*#define __MIDDLE_INTERIOR_EDGE__*/
75 #define __LONGEST_INTERIOR_EDGE__
76 
77 #define NOINDEX         -1
78 
79 /* rule count for element types */
80 #ifdef __TWODIM__
81 #define MAX_TRI_RULES   18
82 #define MAX_QUA_RULES   17
83 #else
84 #ifndef DUNE_UGGRID_TET_RULESET
85 #define MAX_TET_RULES   6
86 #endif
87 #define MAX_PYR_RULES   5
88 #define MAX_PRI_RULES   15
89 #define MAX_HEX_RULES   13
90 #endif
91 
92 /* shorthand notation */
93 #define FO                              FATHER_SIDE_OFFSET
94 
95 /****************************************************************************/
96 /*																			*/
97 /* data structures used in this source file (exported data structures are	*/
98 /*		  in the corresponding include file!)								*/
99 /*																			*/
100 /****************************************************************************/
101 
102 /****************************************************************************/
103 /*																			*/
104 /* definition of exported global variables									*/
105 /*																			*/
106 /****************************************************************************/
107 
108 INT NS_DIM_PREFIX MaxRules[TAGS] = {0,0,0,0,0,0,0,0};
109 INT NS_DIM_PREFIX MaxNewCorners[TAGS] = {0,0,0,0,0,0,0,0};
110 INT NS_DIM_PREFIX MaxNewEdges[TAGS] = {0,0,0,0,0,0,0,0};
111 INT NS_DIM_PREFIX CenterNodeIndex[TAGS] = {0,0,0,0,0,0,0,0};
112 REFRULE * NS_DIM_PREFIX RefRules[TAGS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
113 SHORT const* NS_DIM_PREFIX Pattern2Rule[TAGS];
114 
115 #ifdef __THREEDIM__
116 /* define the standard regular rules for tetrahedrons */
117 FULLREFRULEPTR NS_DIM_PREFIX theFullRefRule;
118 #endif
119 
120 
121 /****************************************************************************/
122 /*                                                                          */
123 /* definition of variables global to this source file only (static!)        */
124 /*                                                                          */
125 /****************************************************************************/
126 
127 #ifdef __TWODIM__
128 static REFRULE Empty_Rule =
129 {-1,-1,NO_CLASS,-1,{-1,-1,-1,-1},-1,
130  {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
131  {{-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
132                         {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
133                         {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
134                         {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}};
135 
136 /* define Rules for Triangles */
137 static REFRULE TriangleRules[MAX_TRI_RULES] = {
138   /* T_NOREF */
139   {TRIANGLE,T_NOREF,NO_CLASS,0,
140    {0,0,0,0},0,
141    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
142    {{-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
143                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
144                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
145                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
146 
147   /* T_COPY */
148   {TRIANGLE,T_COPY,RED_CLASS|GREEN_CLASS,1,
149    {0,0,0,0},0,
150    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
151    {{TRIANGLE,{0,1,2,-1},{FO+0,FO+1,FO+2,-1},0},
152                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
153                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
154                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
155 
156   /* T_RED */
157   {TRIANGLE,T_RED,RED_CLASS|GREEN_CLASS|SWITCH_CLASS,4,
158    {1,1,1,0},(1<<3)-1,
159    {{0,1},{1,2},{0,2},{-1,-1},{-1,-1}},
160    {{TRIANGLE,{0,3,5,-1},{FO+0, 3,FO+2,-1},0},
161                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 3,-1},0},
162                              {TRIANGLE,{4,2,5,-1},{ FO+1,FO+2,3,-1},0},
163                              {TRIANGLE,{3,4,5,-1},{ 1, 2, 0,-1},0}}},
164 
165 
166   /* T_BISECT_1 edge 0 bisected */
167   {TRIANGLE,T_BISECT_1_0,RED_CLASS|GREEN_CLASS,2,
168    {1,0,0,0},1,
169    {{0,1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
170    {{TRIANGLE,{0,3,2,-1},{FO+0, 1,FO+2,-1},0},
171                              {TRIANGLE,{3,1,2,-1},{FO+0,FO+1, 0,-1},0},
172                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
173                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
174 
175   /* T_BISECT_1 edge 1 bisected */
176   {TRIANGLE,T_BISECT_1_1,RED_CLASS|GREEN_CLASS,2,
177    {0,1,0,0},1<<1,
178    {{-1,-1},{0,2},{-1,-1},{-1,-1},{-1,-1}},
179    {{TRIANGLE,{0,1,4,-1},{FO+0,FO+1, 1,-1},0},
180                              {TRIANGLE,{0,4,2,-1},{ 0,FO+1,FO+2,-1},0},
181                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
182                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
183 
184   /* T_BISECT_1 edge 2 bisected */
185   {TRIANGLE,T_BISECT_1_2,RED_CLASS|GREEN_CLASS,2,
186    {0,0,1,0},1<<2,
187    {{-1,-1},{-1,-1},{0,2},{-1,-1},{-1,-1}},
188    {{TRIANGLE,{0,1,5,-1},{FO+0, 1,FO+2,-1},0},
189                              {TRIANGLE,{5,1,2,-1},{ 0,FO+1,FO+2,-1},0},
190                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
191                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
192 
193 
194   /* T_BISECT_2_T1 edge 2 not bisected */
195   {TRIANGLE,T_BISECT_2_T1_2,RED_CLASS|GREEN_CLASS,3,
196    {1,1,0,0},(1<<2)-1,
197    {{0,1},{1,2},{-1,-1},{-1,-1},{-1,-1}},
198    {{TRIANGLE,{0,3,2,-1},{FO+0, 2,FO+2,-1},0},
199                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 2,-1},0},
200                              {TRIANGLE,{3,4,2,-1},{ 1,FO+1, 0,-1},0},
201                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
202 
203   /* T_BISECT_2_T1 edge 0 not bisected */
204   {TRIANGLE,T_BISECT_2_T1_0,RED_CLASS|GREEN_CLASS,3,
205    {0,1,1,0},6,
206    {{-1,-1},{0,2},{1,2},{-1,-1},{-1,-1}},
207    {{TRIANGLE,{0,1,4,-1},{FO+0,FO+1, 1,-1},0},
208                              {TRIANGLE,{0,4,5,-1},{ 0, 2,FO+2,-1},0},
209                              {TRIANGLE,{5,4,2,-1},{ 1,FO+1,FO+2,-1},0},
210                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
211 
212   /* T_BISECT_2_T1 edge 1 not bisected */
213   {TRIANGLE,T_BISECT_2_T1_1,RED_CLASS|GREEN_CLASS,3,
214    {1,0,1,0},5,
215    {{0,1},{-1,-1},{1,2},{-1,-1},{-1,-1}},
216    {{TRIANGLE,{0,3,5,-1},{FO+0, 1,FO+2,-1},0},
217                              {TRIANGLE,{3,1,5,-1},{FO+0, 2, 0,-1},0},
218                              {TRIANGLE,{5,1,2,-1},{ 1,FO+1,FO+2,-1},0},
219                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
220 
221   /* T_BISECT_2_T2 edge 1 not bisected */
222   {TRIANGLE,T_BISECT_2_T2_1,RED_CLASS|GREEN_CLASS,3,
223    {1,0,1,0},5,
224    {{0,1},{-1,-1},{0,2},{-1,-1},{-1,-1}},
225    {{TRIANGLE,{0,3,5,-1},{FO+0, 1,FO+2,-1},0},
226                              {TRIANGLE,{5,3,2,-1},{ 0, 2,FO+2,-1},0},
227                              {TRIANGLE,{3,1,2,-1},{FO+0,FO+1, 1,-1},0},
228                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
229 
230   /* T_BISECT_2_T2 edge 2 not bisected */
231   {TRIANGLE,T_BISECT_2_T2_2,RED_CLASS|GREEN_CLASS,3,
232    {1,1,0,0},3,
233    {{0,1},{0,2},{-1,-1},{-1,-1},{-1,-1}},
234    {{TRIANGLE,{0,3,4,-1},{FO+0, 1, 2,-1},0},
235                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 0,-1},0},
236                              {TRIANGLE,{0,4,2,-1},{ 0,FO+1,FO+2,-1},0},
237                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
238 
239   /* T_BISECT_2_T2 edge 0 not bisected */
240   {TRIANGLE,T_BISECT_2_T2_0,RED_CLASS|GREEN_CLASS,3,
241    {0,1,1,0},6,
242    {{-1,-1},{1,2},{0,2},{-1,-1},{-1,-1}},
243    {{TRIANGLE,{0,1,5,-1},{FO+0, 1,FO+2,-1},0},
244                              {TRIANGLE,{5,1,4,-1},{ 0,FO+1, 2,-1},0},
245                              {TRIANGLE,{5,4,2,-1},{ 1,FO+1,FO+2,-1},0},
246                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
247 
248   /* T_BISECT_2_Q edge 0 not bisected */
249   {TRIANGLE,T_BISECT_2_Q_0,RED_CLASS|GREEN_CLASS,2,
250    {0,1,1,0},6,
251    {{-1,-1},{0,2},{0,3},{-1,-1},{-1,-1}},
252    {{QUADRILATERAL,{0,1,4,5},{FO+0,FO+1, 1,FO+2},0},
253                              {TRIANGLE,{5,4,2,-1},{ 0,FO+1,FO+2,-1},0},
254                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
255                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
256 
257   /* T_BISECT_2_Q edge 1 not bisected */
258   {TRIANGLE,T_BISECT_2_Q_1,RED_CLASS|GREEN_CLASS,2,
259    {1,0,1,0},5,
260    {{0,1},{-1,-1},{0,2},{-1,-1},{-1,-1}},
261    {{TRIANGLE,{0,3,5,-1},{FO+0, 1,FO+2,-1},0},
262                              {QUADRILATERAL,{3,1,2,5},{FO+0,FO+1,FO+2, 0},0},
263                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
264                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
265 
266   /* T_BISECT_2_Q edge 2 not bisected */
267   {TRIANGLE,T_BISECT_2_Q_2,RED_CLASS|GREEN_CLASS,2,
268    {1,1,0,0},3,
269    {{0,1},{0,2},{-1,-1},{-1,-1},{-1,-1}},
270    {{QUADRILATERAL,{0,3,4,2},{FO+0, 1,FO+1,FO+2},0},
271                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 0,-1},0},
272                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
273                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
274 
275   /* T_BISECT_3 edge 0 */
276   {TRIANGLE,T_BISECT_3_0,RED_CLASS|GREEN_CLASS,4,
277    {1,1,1,0},7,
278    {{0,1},{3,2},{0,2},{-1,-1},{-1,-1}},
279    {{TRIANGLE,{0,3,5,-1},{FO+0, 1,FO+2,-1},0},
280                              {TRIANGLE,{5,3,2,-1},{ 0, 2,FO+2,-1},0},
281                              {TRIANGLE,{3,4,2,-1},{ 3,FO+1, 1,-1},0},
282                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 2,-1},0}}},
283 
284   /* T_BISECT_3 edge 1 */
285   {TRIANGLE,T_BISECT_3_1,RED_CLASS|GREEN_CLASS,4,
286    {1,1,1,0},7,
287    {{0,1},{0,2},{1,2},{-1,-1},{-1,-1}},
288    {{TRIANGLE,{0,3,4,-1},{FO+0, 3, 1,-1},0},
289                              {TRIANGLE,{0,4,5,-1},{ 0, 2,FO+2,-1},0},
290                              {TRIANGLE,{5,4,2,-1},{ 1,FO+1,FO+2,-1},0},
291                              {TRIANGLE,{3,1,4,-1},{FO+0,FO+1, 0,-1},0}}},
292 
293   /* T_BISECT_3 edge 2 */
294   {TRIANGLE,T_BISECT_3_2,RED_CLASS|GREEN_CLASS,4,
295    {1,1,1,0},7,
296    {{0,1},{2,2},{1,2},{-1,-1},{-1,-1}},
297    {{TRIANGLE,{0,3,5,-1},{FO+0, 1,FO+2,-1},0},
298                              {TRIANGLE,{3,1,5,-1},{FO+0, 2, 0,-1},0},
299                              {TRIANGLE,{5,1,4,-1},{ 1,FO+1, 3,-1},0},
300                              {TRIANGLE,{5,4,2,-1},{ 2,FO+1,FO+2,-1},0}}},
301 
302 };
303 
304 /* define Rules for Quadrilaterals */
305 static REFRULE QuadrilateralRules[MAX_QUA_RULES] =
306 {
307   /* Q_NOREF */
308   {QUADRILATERAL,Q_NOREF,NO_CLASS,0,
309    {0,0,0,0},0,
310    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
311    {{-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
312                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
313                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
314                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
315 
316   /* Q_COPY */
317   {QUADRILATERAL,Q_COPY,RED_CLASS|GREEN_CLASS,1,
318    {0,0,0,0},0,
319    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
320    {{QUADRILATERAL,{0,1,2,3},{FO+0,FO+1,FO+2,FO+3},-1},
321                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
322                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
323                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
324 
325   /* Q_RED */
326   {QUADRILATERAL,Q_RED,RED_CLASS|GREEN_CLASS|SWITCH_CLASS,4,
327    {1,1,1,1,1},(1<<5)-1,
328    {{0,1},{1,2},{2,3},{3,0},{0,2}},
329    {{QUADRILATERAL,{0,4,8,7},{FO+0, 1, 3,FO+3},-1},
330                              {QUADRILATERAL,{4,1,5,8},{FO+0,FO+1, 2, 0},-1},
331                              {QUADRILATERAL,{8,5,2,6},{ 1,FO+1,FO+2, 3},-1},
332                              {QUADRILATERAL,{7,8,6,3},{ 0, 2,FO+2,FO+3},-1}}},
333 
334   /* Q_CLOSE_1 edge 0 and 1 bisected */
335   {QUADRILATERAL,Q_CLOSE_1_0,RED_CLASS|GREEN_CLASS,3,
336    {1,1,0,0,1},3+16,
337    {{0,1},{1,2},{-1,-1},{-1,-1},{0,2}},
338    {{QUADRILATERAL,{0,4,8,3},{FO+0, 1, 2,FO+3},-1},
339                              {QUADRILATERAL,{4,1,5,8},{FO+0,FO+1, 2, 0},-1},
340                              {QUADRILATERAL,{8,5,2,3},{ 1,FO+1,FO+2, 0},-1},
341                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
342 
343   /* Q_CLOSE_1 edge 1 and 2 bisected */
344   {QUADRILATERAL,Q_CLOSE_1_1,RED_CLASS|GREEN_CLASS,3,
345    {0,1,1,0,1},6+16,
346    {{-1,-1},{0,2},{1,3},{-1,-1},{0,3}},
347    {{QUADRILATERAL,{0,1,5,8},{FO+0,FO+1, 1, 2},-1},
348                              {QUADRILATERAL,{8,5,2,6},{ 0,FO+1,FO+2, 2},-1},
349                              {QUADRILATERAL,{0,8,6,3},{ 0, 1,FO+2,FO+3},-1},
350                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
351 
352   /* Q_CLOSE_1 edge 2 and 3 bisected */
353   {QUADRILATERAL,Q_CLOSE_1_2,RED_CLASS|GREEN_CLASS,3,
354    {0,0,1,1,1},12+16,
355    {{-1,-1},{-1,-1},{1,3},{0,3},{0,2}},
356    {{QUADRILATERAL,{0,1,8,7},{FO+0, 1, 2,FO+3},-1},
357                              {QUADRILATERAL,{8,1,2,6},{ 0,FO+1,FO+2, 2},-1},
358                              {QUADRILATERAL,{7,8,6,3},{ 0, 1,FO+2,FO+3},-1},
359                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
360 
361   /* Q_CLOSE_1 edge 0 and 3 bisected */
362   {QUADRILATERAL,Q_CLOSE_1_3,RED_CLASS|GREEN_CLASS,3,
363    {1,0,0,1,1},9+16,
364    {{0,1},{-1,-1},{-1,-1},{0,3},{0,2}},
365    {{QUADRILATERAL,{0,4,8,7},{FO+0, 1, 2,FO+3},-1},
366                              {QUADRILATERAL,{4,1,2,8},{FO+0,FO+1, 2, 0},-1},
367                              {QUADRILATERAL,{7,8,2,3},{ 0, 1,FO+2,FO+3},-1},
368                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
369 
370   /* Q_BLUE edge 0 and 2 bisected */
371   {QUADRILATERAL,Q_BLUE_0,RED_CLASS|GREEN_CLASS,2,
372    {1,0,1,0,0},5,
373    {{0,1},{-1,-1},{0,2},{-1,-1},{-1,-1}},
374    {{QUADRILATERAL,{0,4,6,3},{FO+0, 1,FO+2,FO+3},-1},
375                              {QUADRILATERAL,{4,1,2,6},{FO+0,FO+1,FO+2, 0},-1},
376                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
377                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
378 
379   /* Q_BLUE edge 1 and 3 bisected */
380   {QUADRILATERAL,Q_BLUE_1,RED_CLASS|GREEN_CLASS,2,
381    {0,1,0,1,0},10,
382    {{-1,-1},{0,2},{-1,-1},{0,3},{-1,-1}},
383    {{QUADRILATERAL,{0,1,5,7},{FO+0,FO+1, 1,FO+3},-1},
384                              {QUADRILATERAL,{7,5,2,3},{ 0,FO+1,FO+2,FO+3},-1},
385                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1},
386                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
387 
388   /* Q_CLOSE_2 edge 0 bisected */
389   {QUADRILATERAL,Q_CLOSE_2_0,RED_CLASS|GREEN_CLASS,3,
390    {1,0,0,0,1},1+16,
391    {{0,1},{-1,-1},{-1,-1},{-1,-1},{0,2}},
392    {{QUADRILATERAL,{0,4,8,3},{FO+0, 1, 2,FO+3},-1},
393                              {QUADRILATERAL,{4,1,2,8},{FO+0,FO+1, 2, 0},-1},
394                              {TRIANGLE,{8,2,3,-1},{ 1,FO+2, 0,-1},-1},
395                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
396 
397   /* Q_CLOSE_2 edge 1 bisected */
398   {QUADRILATERAL,Q_CLOSE_2_1,RED_CLASS|GREEN_CLASS,3,
399    {0,1,0,0,1},2+16,
400    {{-1,-1},{0,2},{-1,-1},{-1,-1},{0,3}},
401    {{QUADRILATERAL,{0,1,5,8},{FO+0,FO+1, 1, 2},-1},
402                              {QUADRILATERAL,{8,5,2,3},{ 0,FO+1,FO+2, 2},-1},
403                              {TRIANGLE,{0,8,3,-1},{ 0, 1,FO+3,-1},-1},
404                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
405 
406   /* Q_CLOSE_2 edge 2 bisected */
407   {QUADRILATERAL,Q_CLOSE_2_2,RED_CLASS|GREEN_CLASS,3,
408    {0,0,1,0,1},4+16,
409    {{-1,-1},{-1,-1},{1,3},{-1,-1},{0,2}},
410    {{TRIANGLE,{0,1,8,-1},{FO+0, 1, 2,-1},-1},
411                              {QUADRILATERAL,{8,1,2,6},{ 0,FO+1,FO+2, 2},-1},
412                              {QUADRILATERAL,{0,8,6,3},{ 0, 1,FO+2,FO+3},-1},
413                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
414 
415   /* Q_CLOSE_2 edge 3 bisected */
416   {QUADRILATERAL,Q_CLOSE_2_3,RED_CLASS|GREEN_CLASS,3,
417    {0,0,0,1,1},8+16,
418    {{-1,-1},{-1,-1},{-1,-1},{0,3},{0,2}},
419    {{QUADRILATERAL,{0,1,8,7},{FO+0, 1, 2,FO+3},-1},
420                              {TRIANGLE,{1,2,8,-1},{FO+1, 2, 0,-1},-1},
421                              {QUADRILATERAL,{7,8,2,3},{ 0, 1,FO+2,FO+3},-1},
422                              {-1,{-1,-1,-1,-1},{-1,-1,-1,-1},-1}}},
423 
424   /* Q_CLOSE_3 edge 0 not bisected */
425   {QUADRILATERAL,Q_CLOSE_3_0,RED_CLASS|GREEN_CLASS,4,
426    {0,1,1,1,0},14,
427    {{-1,-1},{0,2},{1,2},{0,3},{-1,-1}},
428    {{QUADRILATERAL,{0,1,5,7},{FO+0,FO+1, 1,FO+3},-1},
429                              {TRIANGLE,{7,5,6,-1},{ 0, 2, 3,-1},-1},
430                              {TRIANGLE,{5,2,6,-1},{FO+1,FO+2, 1,-1},-1},
431                              {TRIANGLE,{7,6,3,-1},{ 1,FO+2,FO+3,-1},-1}}},
432 
433   /* Q_CLOSE_3 edge 1 not bisected */
434   {QUADRILATERAL,Q_CLOSE_3_1,RED_CLASS|GREEN_CLASS,4,
435    {1,0,1,1,0},13,
436    {{0,1},{-1,-1},{1,2},{0,2},{-1,-1}},
437    {{TRIANGLE,{0,4,7,-1},{FO+0, 1,FO+3,-1},-1},
438                              {TRIANGLE,{7,4,6,-1},{ 0, 3, 2,-1},-1},
439                              {TRIANGLE,{7,6,3,-1},{ 1,FO+2,FO+3,-1},-1},
440                              {QUADRILATERAL,{4,1,2,6},{FO+0,FO+1,FO+2, 1},-1}}},
441 
442   /* Q_CLOSE_3 edge 2 not bisected */
443   {QUADRILATERAL,Q_CLOSE_3_2,RED_CLASS|GREEN_CLASS,4,
444    {1,1,0,1,0},11,
445    {{0,1},{2,2},{-1,-1},{0,2},{-1,-1}},
446    {{TRIANGLE,{0,4,7,-1},{FO+0, 1,FO+3,-1},-1},
447                              {TRIANGLE,{4,5,7,-1},{ 2, 3, 0,-1},-1},
448                              {TRIANGLE,{4,1,5,-1},{FO+0,FO+1, 1,-1},-1},
449                              {QUADRILATERAL,{7,5,2,3},{ 1,FO+1,FO+2,FO+3},-1}}},
450 
451   /* Q_CLOSE_3 edge 3 not bisected */
452   {QUADRILATERAL,Q_CLOSE_3_3,RED_CLASS|GREEN_CLASS,4,
453    {1,1,1,0,0},7,
454    {{0,1},{2,2},{0,2},{-1,-1},{-1,-1}},
455    {{QUADRILATERAL,{0,4,6,3},{FO+0, 1,FO+2,FO+3},-1},
456                              {TRIANGLE,{4,5,6,-1},{ 2, 3, 0,-1},-1},
457                              {TRIANGLE,{4,1,5,-1},{FO+0,FO+1, 1,-1},-1},
458                              {TRIANGLE,{5,2,6,-1},{FO+1,FO+2, 1,-1},-1}}}
459 
460 };
461 
462 #endif
463 
464 #ifdef __THREEDIM__
465 
466 static INT theBFRRDirID;      /* env type for BestFullRefRule       */
467 static INT theBFRRVarID;
468 
469 #ifndef DUNE_UGGRID_TET_RULESET
470 /* define the regular rules for tetrahedron */
471 static REFRULE TetrahedronRules[MAX_TET_RULES] =
472 {
473   /* TET_NO_REF */
474   {TETRAHEDRON,0,NO_CLASS,0,
475    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
476    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
477                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
478                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
479                     {-1,-1}},
480    {{-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
481                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
482                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
483                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
484                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
485                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
486                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
487                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
488                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
489                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
490                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
491 
492   /* TET_COPY */
493   {TETRAHEDRON,1,YELLOW_CLASS,1,
494    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
495    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
496                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
497                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
498                     {-1,-1}},
499    {{TETRAHEDRON,{ 0, 1, 2, 3,-1,-1,-1,-1},{FO+0,FO+1,FO+2,FO+3,-1,-1},-1},
500                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
501                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
502                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
503                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
504                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
505                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
506                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
507                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
508                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
509                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
510                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
511 
512   /* TET_RED equals TET_RED_2_4 */
513   {TETRAHEDRON,2,RED_CLASS|SWITCH_CLASS,8,
514    {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},(1<<6)-1,
515 
516    /* sonandnode */
517    {{0,1},{1,1},{0,2},{0,3},{1,2},{2,2},
518                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
519                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
520                     {-1,-1}},
521 
522    /* sons */
523    {{TETRAHEDRON,{0,4,6,7,-1,-1,-1,-1},{FO+0,4,FO+2,FO+3,-1,-1},0x0},
524                     {TETRAHEDRON,{4,5,8,1,-1,-1,-1,-1},{5,FO+1,FO+3,FO+0,-1,-1},
525                           0x3<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x3<<(2*3))},
526                     {TETRAHEDRON,{5,6,9,2,-1,-1,-1,-1},{6,FO+2,FO+1,FO+0,-1,-1},
527                           0x4<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x1<<(2*3)) | (0x3<<(3*3))},
528                     {TETRAHEDRON,{7,8,9,3,-1,-1,-1,-1},{7,FO+1,FO+2,FO+3,-1,-1},
529                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
530                     {TETRAHEDRON,{4,6,7,8,-1,-1,-1,-1},{0,7,FO+3,5,-1,-1},
531                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
532                     {TETRAHEDRON,{4,5,6,8,-1,-1,-1,-1},{FO+0,6,4,1,-1,-1},
533                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
534                     {TETRAHEDRON,{5,6,8,9,-1,-1,-1,-1},{5,7,FO+1,2,-1,-1},
535                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
536                     {TETRAHEDRON,{6,7,8,9,-1,-1,-1,-1},{4,3,6,FO+2,-1,-1},
537                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
538                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
539                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
540                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
541                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
542 
543   /* TET_RED_0_5 */
544   {TETRAHEDRON,3,RED_CLASS|SWITCH_CLASS,8,
545    {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},(1<<6)-1,
546 
547    /* sonandnode */
548    {{1,0},{0,0},{0,1},{2,0},{1,2},{0,2},
549                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
550                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
551                     {-1,-1}},
552 
553    /* sons */
554    {{TETRAHEDRON,{5,6,9,2,-1,-1,-1,-1},{4,FO+2,FO+1,FO+0,-1,-1},0x0},
555                     {TETRAHEDRON,{4,5,8,1,-1,-1,-1,-1},{5,FO+1,FO+3,FO+0,-1,-1},
556                           0x3<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x3<<(2*3))},
557                     {TETRAHEDRON,{7,8,9,3,-1,-1,-1,-1},{6,FO+1,FO+2,FO+3,-1,-1},
558                           0x4<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x1<<(2*3)) | (0x3<<(3*3))},
559                     {TETRAHEDRON,{0,4,6,7,-1,-1,-1,-1},{FO+0,7,FO+2,FO+3,-1,-1},
560                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
561                     {TETRAHEDRON,{4,5,6,9,-1,-1,-1,-1},{FO+0,0,7,5,-1,-1},
562                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
563                     {TETRAHEDRON,{5,8,9,4,-1,-1,-1,-1},{FO+1,6,4,1,-1,-1},
564                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
565                     {TETRAHEDRON,{4,7,8,9,-1,-1,-1,-1},{FO+3,2,5,7,-1,-1},
566                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
567                     {TETRAHEDRON,{4,6,7,9,-1,-1,-1,-1},{3,FO+2,6,4,-1,-1},
568                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
569                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
570                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
571                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
572                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
573 
574   /* TET_RED_1_3 */
575   {TETRAHEDRON,4,RED_CLASS|SWITCH_CLASS,8,
576    {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},(1<<6)-1,
577 
578    /* sonandnode */
579    {{1,1},{1,1},{2,2},{0,0},{0,1},{0,2},
580                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
581                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
582                     {-1,-1}},
583 
584    /* sons */
585    {{TETRAHEDRON,{7,8,9,3,-1,-1,-1,-1},{4,FO+1,FO+2,FO+3,-1,-1},0x0},
586                     {TETRAHEDRON,{4,5,8,1,-1,-1,-1,-1},{5,FO+1,FO+3,FO+0,-1,-1},
587                           0x3<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x3<<(2*3))},
588                     {TETRAHEDRON,{0,4,6,7,-1,-1,-1,-1},{FO+0,6,FO+2,FO+3,-1,-1},
589                           0x4<<PATHDEPTHSHIFT | 0x1 | (0x3<<3) | (0x1<<(2*3)) | (0x3<<(3*3))},
590                     {TETRAHEDRON,{5,6,9,2,-1,-1,-1,-1},{7,FO+2,FO+1,FO+0,-1,-1},
591                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
592                     {TETRAHEDRON,{5,7,8,9,-1,-1,-1,-1},{5,0,FO+1,7,-1,-1},
593                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
594                     {TETRAHEDRON,{4,5,7,8,-1,-1,-1,-1},{6,4,FO+3,1,-1,-1},
595                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
596                     {TETRAHEDRON,{4,5,6,7,-1,-1,-1,-1},{FO+0,7,2,5,-1,-1},
597                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
598                     {TETRAHEDRON,{5,6,7,9,-1,-1,-1,-1},{6,FO+2,4,3,-1,-1},
599                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
600                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
601                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
602                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
603                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
604 
605   /* TET_RED_HEX */
606   {TETRAHEDRON,5,RED_CLASS|SWITCH_CLASS,4,
607    {1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},(1<<11)-1,
608 
609    /* sonandnode */
610    {{0,2},{1,3},{0,0},{0,5},{3,6},{3,4},
611                     {0,3},{0,6},{3,7},{0,4},{0,7},{-1,-1},
612                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
613                     {-1,-1}},
614 
615    /* sons */
616    {{HEXAHEDRON,{4,1,5,10,13,8,11,14},{FO+0,FO+3,FO+1,1,2,3},0x0},
617                     {HEXAHEDRON,{5,2,6,10,11,9,12,14},{FO+0,FO+1,FO+2,2,0,3},0x0},
618                     {HEXAHEDRON,{0,4,10,6,7,13,14,12},{FO+0,FO+3,0,1,FO+2,3},0x0},
619                     {HEXAHEDRON,{13,8,11,14,7,3,9,12},{0,FO+3,FO+1,1,2,FO+2},0x0},
620                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
621                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
622                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
623                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
624                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
625                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
626                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
627                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}}
628 
629 };
630 #endif
631 
632 /* define the regular rules for pyramids */
633 static REFRULE PyramidRules[MAX_PYR_RULES] =
634 {
635   /* PYR_NO_REF */
636   {PYRAMID,0,NO_CLASS,0,
637    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
638    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
639                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
640                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
641                     {-1,-1}},
642    {{-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
643                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
644                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
645                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
646                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
647                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
648                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
649                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
650                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
651                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
652                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
653 
654   /* PYR_COPY */
655   {PYRAMID,1,YELLOW_CLASS,1,
656    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
657    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
658                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
659                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
660                     {-1,-1}},
661    {{PYRAMID,{ 0, 1, 2, 3, 4,-1,-1,-1},{FO+0,FO+1,FO+2,FO+3,FO+4,-1},-1},
662                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
663                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
664                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
665                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
666                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
667                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
668                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
669                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
670                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
671                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
672                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
673 
674   /* PYR_RED */
675   {PYRAMID,2,RED_CLASS|SWITCH_CLASS,10,
676    {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},(1<<9)-1,
677 
678    /* sonandnode */
679    {{0,1},{1,2},{2,3},{0,3},{0,4},{1,4},
680                     {2,4},{3,4},{0,2},{-1,-1},{-1,-1},{-1,-1},
681                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
682                     {-1,-1}},
683 
684    /* sons */
685    {{PYRAMID,{ 0, 5, 13, 8, 9,-1,-1,-1},{FO+0,FO+1,4,7,FO+4,-1},-1},
686                     {PYRAMID,{5,1,6,13,10,-1,-1,-1},{FO+0,FO+1,FO+2,5,4,-1},
687                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x1<<3)},
688                     {PYRAMID,{13,6,2,7,11,-1,-1,-1},{FO+0,5,FO+2,FO+3,6,-1},
689                           0x4<<PATHDEPTHSHIFT | 0x2 | (0x1<<3) | (0x3<<(2*3)) | (0x1<<(3*3))},
690                     {PYRAMID,{8,13,7,3,12,-1,-1,-1},{FO+0,7,6,FO+3,FO+4,-1},
691                           0x2<<PATHDEPTHSHIFT | 0x3 | (0x2<<3)},
692                     {TETRAHEDRON,{9,10,5,13,-1,-1,-1,-1},{FO+1,1,0,8,-1,-1},
693                           0x1<<PATHDEPTHSHIFT | 0x2},
694                     {TETRAHEDRON,{10,11,6,13,-1,-1,-1,-1},{FO+2,2,1,8,-1,-1},
695                           0x3<<PATHDEPTHSHIFT | 0x2 | (0x1<<3) | (0x3<<(2*3))},
696                     {TETRAHEDRON,{11,12,7,13,-1,-1,-1,-1},{FO+3,3,2,8,-1,-1},
697                           0x3<<PATHDEPTHSHIFT | 0x3 | (0x2<<3) | (0x2<<(2*3))},
698                     {TETRAHEDRON,{12,9,8,13,-1,-1,-1,-1},{FO+4,0,3,8,-1,-1},
699                           0x1<<PATHDEPTHSHIFT | 0x3},
700                     {PYRAMID,{12,11,10,9,13,-1,-1,-1},{9,6,5,4,7,-1},
701                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x3<<3)},
702                     {PYRAMID,{9,10,11,12,4,-1,-1,-1},{8,FO+1,FO+2,FO+3,FO+4,-1},
703                           0x3<<PATHDEPTHSHIFT | 0x2 | (0x3<<3) | (0x0<<(2*3))},
704                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
705                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
706 
707   /* PYR_bisect_0_1 */
708   {PYRAMID,3,RED_CLASS|SWITCH_CLASS,2,
709    {1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},5,
710 
711    /* sonandnode */
712    {{0,1},{1,2},{2,3},{0,3},{0,4},{1,4},
713                     {2,4},{3,4},{0,2},{-1,-1},{-1,-1},{-1,-1},
714                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
715                     {-1,-1}},
716 
717    /* sons */
718    {{PYRAMID,{ 0, 5, 7, 3, 4,-1,-1,-1},{FO+0,FO+1,1,FO+3,FO+4,-1},-1},
719                     {PYRAMID,{5,1,2,7,4,-1,-1,-1},{FO+0,FO+1,FO+2,FO+3,0,-1},
720                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x1<<3)},
721                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
722                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
723                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
724                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
725                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
726                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
727                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
728                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
729                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
730                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
731 
732   /* PYR_bisect_0_2 */
733   {PYRAMID,4,RED_CLASS|SWITCH_CLASS,2,
734    {0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},10,
735 
736    /* sonandnode */
737    {{0,1},{1,2},{2,3},{0,3},{0,4},{1,4},
738                     {2,4},{3,4},{0,2},{-1,-1},{-1,-1},{-1,-1},
739                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
740                     {-1,-1}},
741 
742    /* sons */
743    {{PYRAMID,{ 0, 1, 6, 8, 4,-1,-1,-1},{FO+0,FO+1,FO+2,1,FO+4,-1},-1},
744                     {PYRAMID,{8,6,2,3,4,-1,-1,-1},{FO+0,0,FO+2,FO+3,FO+4,-1},
745                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x1<<3)},
746                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
747                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
748                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
749                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
750                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
751                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
752                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
753                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
754                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
755                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}}
756 
757 };
758 
759 /* define the regular rules for prisms */
760 static REFRULE PrismRules[MAX_PRI_RULES] =
761 {
762   /* PRI_NO_REF */
763   {PRISM,0,NO_CLASS,0,
764    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
765    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
766                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
767                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
768                     {-1,-1}},
769    {{-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
770                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
771                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
772                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
773                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
774                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
775                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
776                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
777                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
778                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
779                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
780 
781   /* PRI_COPY */
782   {PRISM,1,YELLOW_CLASS,1,
783    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
784    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
785                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
786                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
787                     {-1,-1}},
788    {{PRISM,{ 0, 1, 2, 3, 4, 5,-1,-1},{FO+0,FO+1,FO+2,FO+3,FO+4,-1},-1},
789                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
790                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
791                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
792                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
793                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
794                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
795                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
796                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
797                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
798                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
799                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
800 
801   /* PRI_RED */
802   {PRISM,2,RED_CLASS|SWITCH_CLASS,8,
803    {1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0},
804    (1<<9)-1+(1<<10)+(1<<11)+(1<<12),
805 
806    /* sonandnode */
807    {{0,1},{1,1},{0,2},{0,3},{1,4},{2,5},
808                     {4,4},{5,5},{4,5},{-1,-1},{0,4},{1,5},{0,5},
809                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
810                     {-1,-1}},
811 
812    /* sons */
813    {{PRISM,{0,6,8,9,16,18,-1,-1},{FO+0,FO+1,2,FO+3,4,-1},-1},
814                     {PRISM,{6,1,7,16,10,17,-1,-1},{FO+0,FO+1,FO+2,2,5,-1},
815                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
816                     {PRISM,{8,6,7,18,16,17,-1,-1},{FO+0,0,1,3,6,-1},
817                           0x1<<PATHDEPTHSHIFT | 0x2},
818                     {PRISM,{8,7,2,18,17,11,-1,-1},{FO+0,2,FO+2,FO+3,7,-1},
819                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x3<<3)},
820                     {PRISM,{9,16,18,3,12,14,-1,-1},{0,FO+1,6,FO+3,FO+4,-1},
821                           0x1<<PATHDEPTHSHIFT | 0x4},
822                     {PRISM,{16,10,17,12,4,13,-1,-1},{1,FO+1,FO+2,6,FO+4,-1},
823                           0x3<<PATHDEPTHSHIFT | 0x2 | (0x2<<3) | (0x4<<(2*3))},
824                     {PRISM,{18,16,17,14,12,13,-1,-1},{2,4,5,7,FO+4,-1},
825                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x4<<3)},
826                     {PRISM,{18,17,11,14,13,5,-1,-1},{3,6,FO+2,FO+3,FO+4,-1},
827                           0x3<<PATHDEPTHSHIFT | 0x2 | (0x3<<3) | (0x4<<(2*3))},
828                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
829                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
830                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
831                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
832 
833   /* PRI_QUADSECT */
834   {PRISM,3,RED_CLASS|SWITCH_CLASS,4,
835    {1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0},
836    (1<<3)-1+(1<<6)+(1<<7)+(1<<8),
837 
838    /* sonandnode */
839    {{0,0},{0,0},{0,0},{-1,-1},{-1,-1},{-1,-1},
840                     {0,0},{0,0},{0,0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
841                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
842                     {-1,-1}},
843 
844    /* sons */
845    {{PRISM,{0,6,8,3,12,14,-1,-1},{FO+0,FO+1,2,FO+3,FO+4,-1},-1},
846                     {PRISM,{6,1,7,12,4,13,-1,-1},{FO+0,FO+1,FO+2,2,FO+4,-1},
847                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
848                     {PRISM,{8,6,7,14,12,13,-1,-1},{FO+0,0,1,3,FO+4,-1},
849                           0x1<<PATHDEPTHSHIFT | 0x2},
850                     {PRISM,{8,7,2,14,13,5,-1,-1},{FO+0,2,FO+2,FO+3,FO+4,-1},
851                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x3<<3)},
852                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
853                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
854                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
855                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
856                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
857                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
858                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
859                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
860 
861   /* PRI_BISECT_0_1 */
862   {PRISM,4,RED_CLASS|SWITCH_CLASS,2,
863    {1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
864    1 + (1<<6),
865 
866    /* sonandnode */
867    {{0,1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
868                     {0,4},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
869                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
870                     {-1,-1}},
871 
872    /* sons */
873    {{PRISM,{0,6,2,3,12,5,-1,-1},{FO+0,FO+1,1,FO+3,FO+4,-1},-1},
874                     {PRISM,{6,1,2,12,4,5,-1,-1},{FO+0,FO+1,FO+2,0,FO+4,-1},
875                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
876                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
877                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
878                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
879                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
880                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
881                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
882                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
883                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
884                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
885                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
886 
887   /* PRI_BISECT_0_2 */
888   {PRISM,5,RED_CLASS|SWITCH_CLASS,2,
889    {0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
890    (1<<1) + (1<<7),
891 
892    /* sonandnode */
893    {{-1,-1},{0,1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
894                     {-1,-1},{0,4},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
895                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
896                     {-1,-1}},
897 
898    /* sons */
899    {{PRISM,{0,7,2,3,13,5,-1,-1},{FO+0,1,FO+2,FO+3,FO+4,-1},-1},
900                     {PRISM,{0,1,7,3,4,13,-1,-1},{FO+0,FO+1,FO+2,0,FO+4,-1},
901                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
902                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
903                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
904                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
905                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
906                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
907                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
908                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
909                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
910                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
911                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
912 
913   /* PRI_BISECT_0_3 */
914   {PRISM,6,RED_CLASS|SWITCH_CLASS,2,
915    {0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
916    (1<<2) + (1<<8),
917 
918    /* sonandnode */
919    {{-1,-1},{-1,-1},{0,2},{-1,-1},{-1,-1},{-1,-1},
920                     {-1,-1},{-1,-1},{0,5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
921                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
922                     {-1,-1}},
923 
924    /* sons */
925    {{PRISM,{0,1,8,3,4,14,-1,-1},{FO+0,FO+1,1,FO+3,FO+4,-1},-1},
926                     {PRISM,{8,1,2,14,4,5,-1,-1},{FO+0,0,FO+2,FO+3,FO+4,-1},
927                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
928                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
929                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
930                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
931                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
932                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
933                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
934                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
935                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
936                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
937                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
938 
939   /* PRI_BISECT_1_2 */
940   {PRISM,7,RED_CLASS|SWITCH_CLASS,2,
941    {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
942    (1<<3) + (1<<4) + (1<<5),
943 
944    /* sonandnode */
945    {{-1,-1},{-1,-1},{-1,-1},{0,0},{0,0},{0,0},
946                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
947                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
948                     {-1,-1}},
949 
950    /* sons */
951    {{PRISM,{0,1,2,9,10,11,-1,-1},{FO+0,FO+1,FO+2,FO+3,1,-1},-1},
952                     {PRISM,{9,10,11,3,4,5,-1,-1},{0,FO+1,FO+2,FO+3,FO+4,-1},
953                           0x2<<PATHDEPTHSHIFT | 0x2 | (0x2<<3)},
954                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
955                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
956                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
957                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
958                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
959                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
960                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
961                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
962                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
963                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
964 
965   /* PRI_BISECT_HEX0 */
966   {PRISM,8,RED_CLASS|SWITCH_CLASS,2,
967    {1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0},
968    1+(1<<2)+(1<<6)+(1<<8),
969 
970    /* sonandnode */
971    {{0,1},{-1,-1},{0,2},{-1,-1},{-1,-1},{-1,-1},
972                     {0,4},{-1,-1},{0,5},{-1,-1},{-1,-1},{-1,-1},
973                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
974                     {-1,-1}},
975 
976    /* sons */
977    {{PRISM,{0,6,8,3,12,14,-1,-1},{FO+0,FO+1,1,FO+3,FO+4,-1},-1},
978                     {HEXAHEDRON,{6,1,2,8,12,4,5,14},{FO+0,FO+1,FO+2,FO+3,0,FO+4},
979                           0x1<<PATHDEPTHSHIFT | 0x2},
980                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
981                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
982                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
983                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
984                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
985                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
986                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
987                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
988                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
989                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
990 
991   /* PRI_BISECT_HEX1 */
992   {PRISM,9,RED_CLASS|SWITCH_CLASS,2,
993    {0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
994    (1<<1)+(1<<2)+(1<<7)+(1<<8),
995 
996    /* sonandnode */
997    {{-1,-1},{0,2},{0,3},{-1,-1},{-1,-1},{-1,-1},
998                     {-1,-1},{0,6},{0,7},{-1,-1},{-1,-1},{-1,-1},
999                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1000                     {-1,-1}},
1001 
1002    /* sons */
1003    {{HEXAHEDRON,{0,1,7,8,3,4,13,14},{FO+0,FO+1,FO+2,1,FO+3,FO+4},-1},
1004                     {PRISM,{7,8,2,13,14,5,-1,-1},{FO+0,0,FO+2,FO+3,FO+4,-1},
1005                           0x1<<PATHDEPTHSHIFT | 0x3},
1006                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1007                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1008                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1009                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1010                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1011                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1012                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1013                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1014                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1015                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1016 
1017   /* PRI_BISECT_HEX2 */
1018   {PRISM,10,RED_CLASS|SWITCH_CLASS,2,
1019    {1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0},
1020    1+(1<<1)+(1<<6)+(1<<7),
1021 
1022    /* sonandnode */
1023    {{0,1},{0,2},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1024                     {0,5},{0,6},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1025                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1026                     {-1,-1}},
1027 
1028    /* sons */
1029    {{HEXAHEDRON,{6,7,2,0,12,13,5,3},{FO+0,1,FO+2,FO+3,FO+1,FO+4},-1},
1030                     {PRISM,{6,1,7,12,4,13,-1,-1},{FO+0,FO+1,FO+2,0,FO+4,-1},
1031                           0x1<<PATHDEPTHSHIFT | 0x2},
1032                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1033                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1034                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1035                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1036                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1037                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1038                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1039                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1040                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1041                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1042 
1043   /* PRI_trisect_0_4 */
1044   {PRISM,11,RED_CLASS|SWITCH_CLASS,3,
1045    {1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0},
1046    (1<<3)-1 + (1<<6) + (1<<7) + (1<<8) + (1<<9) + (1<<13),
1047 
1048    /* sonandnode */
1049    {{0,1},{1,1},{0,2},{0,3},{1,4},{2,5},
1050                     {4,4},{5,5},{4,5},{-1,-1},{0,4},{1,5},{0,5},
1051                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1052                     {-1,-1}},
1053 
1054    /* sons */
1055    {{HEXAHEDRON,{ 0, 6,15,8,3,12,19,14},{FO+0,FO+1,1,2,FO+3,FO+4},-1},
1056                     {HEXAHEDRON,{ 6, 1, 7,15,12,4,13,19},{FO+0,FO+1,FO+2,2,0,FO+4},
1057               0x1<<PATHDEPTHSHIFT | 0x2},
1058                     {HEXAHEDRON,{ 8,15,7,2,14,19,13,5},{FO+0,0,1,FO+2,FO+3,FO+4},
1059               0x1<<PATHDEPTHSHIFT | 0x2},
1060                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1061                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1062                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1063                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1064                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1065                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1066                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1067                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1068                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1069 
1070   /* PRI_rotate_l */
1071   {PRISM,12,RED_CLASS,1,
1072    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
1073    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1074                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1075                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1076                     {-1,-1}},
1077    {{PRISM,{ 1, 2, 0, 4, 5, 3,-1,-1},{FO+0,FO+2,FO+3,FO+1,FO+4,-1},-1},
1078                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1079                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1080                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1081                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1082                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1083                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1084                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1085                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1086                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1087                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1088                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1089 
1090   /* PRI_rotate_r */
1091   {PRISM,13,RED_CLASS,1,
1092    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
1093    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1094                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1095                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1096                     {-1,-1}},
1097    {{PRISM,{ 2, 0, 1, 5, 3, 4,-1,-1},{FO+0,FO+3,FO+1,FO+2,FO+4,-1},-1},
1098                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1099                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1100                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1101                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1102                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1103                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1104                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1105                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1106                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1107                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1108                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1109 
1110   /* PRI_QUADSECT_HEXPRI0 */
1111   {PRISM,14,RED_CLASS,4,
1112    {1,1,0,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0},
1113    3 + (1<<3) + (1<<4) + (1<<5) + (1<<6) + (1<<7) + (1<<10) + (1<<11),
1114 
1115    {{0,1},{0,2},{-1,-1},{0,4},{1,5},{0,7},
1116                     {3,5},{3,6},{-1,-1},{-1,-1},{0,5},{0,6},
1117                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1118                     {-1,-1}},
1119    {{HEXAHEDRON,{11, 9, 0, 2,17,16,6, 7},{FO+3,3,FO+1,FO+0,FO+2,1},-1},
1120                     {PRISM,{ 6, 1, 7,16,10,17,-1,-1},{FO+0,FO+1,FO+2,0,2,-1},-1},
1121                     {PRISM,{16,10,17,12, 4,13,-1,-1},{1,FO+1,FO+2,3,FO+4,-1},-1},
1122                     {HEXAHEDRON,{ 5, 3, 9,11,13,12,16,17},{FO+3,FO+4,FO+1,0,FO+2,2},-1},
1123                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1124                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1125                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1126                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1127                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1128                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1129                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1130                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}}
1131 
1132 };
1133 
1134 /* define the regular rules for hexahedra */
1135 static REFRULE HexahedronRules[MAX_HEX_RULES] =
1136 {
1137   /* HEX_NO_REF */
1138   {HEXAHEDRON,0,NO_CLASS,0,
1139    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
1140    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1141                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1142                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1143                     {-1,-1}},
1144    {{-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1145                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1146                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1147                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1148                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1149                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1150                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1151                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1152                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1153                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1154                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1155                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1156 
1157   /* HEX_COPY */
1158   {HEXAHEDRON,1,YELLOW_CLASS,1,
1159    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,
1160    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1161                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1162                     {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1163                     {-1,-1}},
1164    {{HEXAHEDRON,{0,1,2,3,4,5,6,7},{FO+0,FO+1,FO+2,FO+3,FO+4,FO+5},-1},
1165                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1166                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1167                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1168                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1169                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1170                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1171                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1172                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1173                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1174                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1175                     {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1176 
1177   /* HEX_RED */
1178   {HEXAHEDRON,2,RED_CLASS|SWITCH_CLASS,8,
1179    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},(1<<19)-1,
1180 
1181    /* sonandnode */
1182    {{0,1},{1,2},{2,3},{3,0},
1183                      {0,4},{1,5},{2,6},{3,7},
1184                      {4,5},{5,6},{6,7},{7,4},
1185                      {0,2},{0,5},{1,6},{2,7},{0,7},{4,6},{0,6}},
1186 
1187    /* sons */
1188    {{HEXAHEDRON,{ 0, 8,20,11,12,21,26,24},{FO+0,FO+1, 1, 3,FO+4, 4},-1},
1189                      {HEXAHEDRON,{ 8, 1, 9,20,21,13,22,26},{FO+0,FO+1,FO+2, 2, 0, 5},
1190                      0x1<<PATHDEPTHSHIFT | 0x2},
1191                      {HEXAHEDRON,{20, 9, 2,10,26,22,14,23},{FO+0, 1,FO+2,FO+3, 3, 6},
1192                      0x2<<PATHDEPTHSHIFT | 0x2 | 0x3<<3},
1193                      {HEXAHEDRON,{11,20,10, 3,24,26,23,15},{FO+0, 0, 2,FO+3,FO+4, 7},
1194                      0x1<<PATHDEPTHSHIFT | 0x3},
1195 
1196                      {HEXAHEDRON,{12,21,26,24, 4,16,25,19},{ 0,FO+1, 5, 7,FO+4,FO+5},
1197                      0x1<<PATHDEPTHSHIFT | 0x5},
1198                      {HEXAHEDRON,{21,13,22,26,16, 5,17,25},{ 1,FO+1,FO+2, 6, 4,FO+5},
1199                      0x2<<PATHDEPTHSHIFT | 0x5 | 0x2<<3},
1200                      {HEXAHEDRON,{26,22,14,23,25,17, 6,18},{ 2, 5,FO+2,FO+3, 7,FO+5},
1201                      0x3<<PATHDEPTHSHIFT | 0x5 | 0x2<<3 | 0x3<<(2*3)},
1202                      {HEXAHEDRON,{24,26,23,15,19,25,18, 7},{ 3, 4, 6,FO+3,FO+4,FO+5},
1203                      0x2<<PATHDEPTHSHIFT | 0x5 | 0x3<<3},
1204                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1205                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1206                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1207                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1208 
1209   /* HEX_bisect_0_1 */
1210   {HEXAHEDRON,3,RED_CLASS|SWITCH_CLASS,2,
1211    {1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0},
1212    1 + (1<<2) + (1<<8) + (1<<10),
1213 
1214    /* sonandnode */
1215    {{0,0},{-1,-1},{0,0},{-1,-1},{-1,-1},{-1,-1},
1216                      {-1,-1},{-1,-1},{0,0},{-1,-1},{0,0},{-1,-1},
1217                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1218                      {-1,-1}},
1219 
1220    /* sons */
1221    {{HEXAHEDRON,{ 0, 8,10,3,4,16,18,7},{FO+0,FO+1, 1,FO+3,FO+4,FO+5},-1},
1222                      {HEXAHEDRON,{ 8, 1, 2,10,16,5,6,18},{FO+0,FO+1,FO+2,FO+3, 0,FO+5},
1223                      0x1<<PATHDEPTHSHIFT | 0x2},
1224                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1225                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1226                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1227                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1228                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1229                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1230                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1231                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1232                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1233                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1234 
1235   /* HEX_bisect_0_2 */
1236   {HEXAHEDRON,4,RED_CLASS|SWITCH_CLASS,2,
1237    {0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0},
1238    (1<<1) + (1<<3) + (1<<9) + (1<<11),
1239 
1240    /* sonandnode */
1241    {{-1,-1},{0,0},{-1,-1},{0,0},{-1,-1},{-1,-1},
1242                      {-1,-1},{-1,-1},{-1,-1},{0,0},{-1,-1},{0,0},
1243                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1244                      {-1,-1}},
1245 
1246    /* sons */
1247    {{HEXAHEDRON,{ 0, 1,9,11,4,5,17,19},{FO+0,FO+1,FO+2,1,FO+4,FO+5},-1},
1248                      {HEXAHEDRON,{ 11, 9, 2,3,19,17,6,7},{FO+0,0,FO+2,FO+3,FO+4,FO+5},
1249                      0x1<<PATHDEPTHSHIFT | 0x2},
1250                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1251                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1252                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1253                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1254                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1255                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1256                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1257                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1258                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1259                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1260 
1261   /* HEX_bisect_0_3 */
1262   {HEXAHEDRON,5,RED_CLASS|SWITCH_CLASS,2,
1263    {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
1264    (1<<4) + (1<<5) + (1<<6) + (1<<7),
1265 
1266    /* sonandnode */
1267    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{0,0},{0,0},
1268                      {0,0},{0,0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1269                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1270                      {-1,-1}},
1271 
1272    /* sons */
1273    {{HEXAHEDRON,{ 0, 1,2,3,12,13,14,15},{FO+0,FO+1,FO+2,FO+3,FO+4,1},-1},
1274                      {HEXAHEDRON,{ 12,13,14,15,4,5,6,7},{0,FO+1,FO+2,FO+3,FO+4,FO+5},
1275                      0x1<<PATHDEPTHSHIFT | 0x2},
1276                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1277                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1278                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1279                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1280                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1281                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1282                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1283                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1284                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1285                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1286 
1287   /* HEX_quadsect_0 */
1288   {HEXAHEDRON,6,RED_CLASS|SWITCH_CLASS,4,
1289    {1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,0},
1290    (1<<4)-1 + (1<<8) + (1<<9) + (1<<10) + (1<<11) + (1<<12) + (1<<17),
1291 
1292    /* sonandnode */
1293    {{0,1},{1,2},{2,3},{0,3},
1294                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},
1295                      {0,5},{1,6},{2,7},{0,7},
1296                      {0,2},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{0,6},{-1,-1}},
1297 
1298    /* sons */
1299    {{HEXAHEDRON,{ 0, 8,20,11,4,16,25,19},{FO+0,FO+1,1,3,FO+4,FO+5},-1},
1300                      {HEXAHEDRON,{ 8, 1, 9,20,16,5,17,25},{FO+0,FO+1,FO+2,2,0,FO+5},
1301                      0x1<<PATHDEPTHSHIFT | 0x2},
1302                      {HEXAHEDRON,{ 20, 9, 2,10,25,17,6,18},{FO+0,1,FO+2,FO+3,3,FO+5},
1303                      0x1<<PATHDEPTHSHIFT | 0x2},
1304                      {HEXAHEDRON,{ 11, 20, 10,3,19,25,18,7},{FO+0,0,2,FO+3,FO+4,FO+5},
1305                      0x1<<PATHDEPTHSHIFT | 0x2},
1306                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1307                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1308                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1309                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1310                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1311                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1312                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1313                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1314 
1315   /* HEX_quadsect_1 */
1316   {HEXAHEDRON,7,RED_CLASS|SWITCH_CLASS,4,
1317    {1,0,1,0,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0},
1318    1 + (1<<2) + (1<<4) + (1<<5) + (1<<6) + (1<<7) + (1<<8) + (1<<10) + (1<<13) + (1<<15),
1319 
1320    /* sonandnode */
1321    {{0,1},{-1,-1},{0,2},{-1,-1},
1322                      {0,4},{1,5},{1,6},{0,7},
1323                      {3,5},{-1,-1},{3,6},{-1,-1},
1324                      {-1,-1},{0,5},{-1,-1},{0,6},{-1,-1},{-1,-1},{-1,-1}},
1325 
1326    /* sons */
1327    {{HEXAHEDRON,{ 0, 8,10,3,12,21,23,15},{FO+0,FO+1,1,FO+3,FO+4,3},-1},
1328                      {HEXAHEDRON,{ 8, 1, 2,10,21,13,14,23},{FO+0,FO+1,FO+2,FO+3,0,2},
1329                      0x1<<PATHDEPTHSHIFT | 0x2},
1330                      {HEXAHEDRON,{ 21, 13, 14,23,16,5,6,18},{1,FO+1,FO+2,FO+3,3,FO+5},
1331                      0x1<<PATHDEPTHSHIFT | 0x2},
1332                      {HEXAHEDRON,{ 12, 21, 23,15,4,16,18,7},{0,FO+1,2,FO+3,FO+4,FO+5},
1333                      0x1<<PATHDEPTHSHIFT | 0x2},
1334                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1335                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1336                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1337                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1338                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1339                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1340                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1341                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1342 
1343   /* HEX_quadsect_2 */
1344   {HEXAHEDRON,8,RED_CLASS|SWITCH_CLASS,4,
1345    {0,1,0,1,1,1,1,1,0,1,0,1,0,0,1,0,1,0,0},
1346    (1<<1) + (1<<3) + (1<<4) + (1<<5) + (1<<6) + (1<<7) + (1<<9) + (1<<11) + (1<<14) + (1<<16),
1347 
1348    /* sonandnode */
1349    {{-1,-1},{0,2},{-1,-1},{0,3},
1350                      {0,4},{0,5},{1,6},{1,7},
1351                      {-1,-1},{3,6},{-1,-1},{3,7},
1352                      {-1,-1},{-1,-1},{0,6},{-1,-1},{0,7},{-1,-1},{-1,-1}},
1353 
1354    /* sons */
1355    {{HEXAHEDRON,{ 0, 1,9,11,12,13,22,24},{FO+0,FO+1,FO+2,1,FO+4,3},-1},
1356                      {HEXAHEDRON,{ 11, 9, 2,3,24,22,14,15},{FO+0,0,FO+2,FO+3,FO+4,2},
1357                      0x1<<PATHDEPTHSHIFT | 0x2},
1358                      {HEXAHEDRON,{ 24, 22, 14,15,19,17,6,7},{1,3,FO+2,FO+3,FO+4,FO+5},
1359                      0x1<<PATHDEPTHSHIFT | 0x2},
1360                      {HEXAHEDRON,{ 12, 13, 22,24,4,5,17,19},{0,FO+1,FO+2,2,FO+4,FO+5},
1361                      0x1<<PATHDEPTHSHIFT | 0x2},
1362                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1363                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1364                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1365                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1366                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1367                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1368                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1369                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1370 
1371   /* HEX_trisect_0 */
1372   {HEXAHEDRON,9,RED_CLASS|SWITCH_CLASS,3,
1373    {1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},(1<<2)+1,
1374 
1375    /* sonandnode */
1376    {{0,0},{-1,-1},{0,0},{-1,-1},{-1,-1},{-1,-1},
1377                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1378                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1379                      {-1,-1}},
1380 
1381    /* sons */
1382    {{PRISM,{0,4,8,3,7,10,-1,-1},{FO+1,FO+4,1,FO+0,FO+3,-1},-1},
1383                      {PRISM,{ 4, 5, 8,7,6,10,-1,-1},{FO+1,FO+5,2,0,FO+3,-1},
1384                      0x1<<PATHDEPTHSHIFT | 0x2},
1385                      {PRISM,{ 5, 1, 8,6,2,10,-1,-1},{FO+1,FO+2,FO+0,1,FO+3,-1},
1386                      0x1<<PATHDEPTHSHIFT | 0x2},
1387                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1388                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1389                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1390                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1391                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1392                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1393                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1394                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1395                      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}}},
1396 
1397   /* HEX_trisect_5 */
1398   {HEXAHEDRON,9,RED_CLASS|SWITCH_CLASS,3,
1399    {0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0},
1400    (1<<8) + (1<<10),
1401 
1402    /* sonandnode */
1403    {{-1,-1},{-1,-1},{-1,-1},{-1,-1},
1404                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},
1405                      {0,0},{-1,-1},{0,0},{-1,-1},
1406                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
1407 
1408    /* sons */
1409    {
1410      {PRISM,{ 4, 16,0,7,18,3,-1,-1},{FO+1,FO+5,1,FO+4,FO+3,-1},-1},
1411      {PRISM,{ 16, 1,0,18,2,3,-1,-1},{FO+1,2,FO+0,0,FO+3,-1},-1},
1412      {PRISM,{ 5, 1,16,6,2,18,-1,-1},{FO+1,FO+2,1,FO+5,FO+3,-1},-1},
1413      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1414      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1415      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1416      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1417      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1418      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1419      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1420      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1421      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}
1422    }},
1423 
1424   /* HEX_bisect_hexpri0 */
1425   {HEXAHEDRON,10,RED_CLASS|SWITCH_CLASS,2,
1426    {0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
1427    (1<<3) + (1<<11),
1428 
1429    /* sonandnode */
1430    {{-1,-1},{-1,-1},{-1,-1},{0,3},
1431                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},
1432                      {-1,-1},{-1,-1},{-1,-1},{0,7},
1433                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
1434 
1435    /* sons */
1436    {
1437      {HEXAHEDRON,{ 0, 1, 2,11, 4, 5, 6,19},{FO+0,FO+1,FO+2,1,FO+4,FO+5},-1},
1438      {PRISM,{11, 2, 3,19, 6, 7,-1,-1},{FO+0,0,FO+2,FO+3,FO+4,-1},-1},
1439      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1440      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1441      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1442      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1443      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1444      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1445      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1446      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1447      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1448      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}
1449    }},
1450 
1451   /* HEX_bisect_hexpri1 */
1452   {HEXAHEDRON,11,RED_CLASS|SWITCH_CLASS,2,
1453    {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
1454    1 + (1<<8),
1455 
1456    /* sonandnode */
1457    {{0,0},{-1,-1},{-1,-1},{-1,-1},
1458                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},
1459                      {0,4},{-1,-1},{-1,-1},{-1,-1},
1460                      {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}},
1461 
1462    /* sons */
1463    {
1464      {HEXAHEDRON,{ 8, 1, 2, 3,16, 5, 6, 7},{FO+0,FO+1,FO+2,FO+3,1,FO+5},-1},
1465      {PRISM,{ 8, 3, 0,16, 7, 4,-1,-1},{FO+0,0,FO+2,FO+3,FO+4,-1},-1},
1466      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1467      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1468      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1469      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1470      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1471      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1472      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1473      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1474      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1},
1475      {-1,{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1},-1}
1476    }}
1477 
1478 };
1479 #endif
1480 
1481 /****************************************************************************/
1482 /*                                                                          */
1483 /* forward declarations of functions used before they are defined           */
1484 /*                                                                          */
1485 /****************************************************************************/
1486 
1487 #ifdef __THREEDIM__
1488 
GetRule_AnisotropicRed(ELEMENT * theElement,INT * Rule)1489 INT NS_DIM_PREFIX GetRule_AnisotropicRed (ELEMENT *theElement, INT *Rule)
1490 {
1491   DOUBLE area,norm;
1492   DOUBLE_VECTOR a,b,c;
1493 
1494   switch (TAG(theElement))
1495   {
1496   case TETRAHEDRON :
1497     *Rule=TET_RED;
1498     return (0);
1499 
1500   case PYRAMID :
1501     *Rule=PYR_RED;
1502     return (0);
1503 
1504   case PRISM :
1505     *Rule=PRI_RED;
1506     V3_SUBTRACT(CVECT(MYVERTEX(CORNER(theElement,1))),CVECT(MYVERTEX(CORNER(theElement,0))),a);
1507     V3_SUBTRACT(CVECT(MYVERTEX(CORNER(theElement,2))),CVECT(MYVERTEX(CORNER(theElement,0))),b);
1508     V3_VECTOR_PRODUCT(a,b,c);
1509     V3_EUKLIDNORM(c,area);
1510     area *= 0.5;
1511     V3_SUBTRACT(CVECT(MYVERTEX(CORNER(theElement,3))),CVECT(MYVERTEX(CORNER(theElement,0))),a);
1512     V3_EUKLIDNORM(a,norm);
1513     if (norm < 0.25*SQRT(area))
1514     {
1515       *Rule=PRI_QUADSECT;
1516       return(1);
1517     }
1518     break;
1519 
1520   case HEXAHEDRON :
1521     *Rule=HEXA_RED;
1522     return (0);
1523 
1524   default :
1525     assert(0);
1526   }
1527 
1528   return (0);
1529 }
1530 
1531 
1532 /****************************************************************************/
1533 /** \brief Compute best full refined refrule for the element
1534 
1535    \param theElement - for that element
1536 
1537    This function computes the best full refined refrule for the element.
1538 
1539    \return
1540    Mark: number of refrule
1541  */
1542 /****************************************************************************/
1543 
ShortestInteriorEdge(ELEMENT * theElement)1544 static INT ShortestInteriorEdge (ELEMENT *theElement)
1545 {
1546   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1547   DOUBLE_VECTOR MidPoints[MAX_EDGES_OF_ELEM];
1548   INT i, flags;
1549   DOUBLE Dist_0_5, Dist_1_3, Dist_2_4;
1550 
1551   /* get physical position of the corners */
1552   for (i=0; i<CORNERS_OF_ELEM(theElement); i++)
1553     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1554 
1555   /* get physical position of the midpoints of the edges */
1556   for (i=0; i<EDGES_OF_ELEM(theElement); i++)
1557     V3_LINCOMB(0.5, Corners[CORNER_OF_EDGE(theElement,i,0)], 0.5, Corners[CORNER_OF_EDGE(theElement,i,1)], MidPoints[i]);
1558 
1559   /* compute distances */
1560   V3_EUKLIDNORM_OF_DIFF(MidPoints[0], MidPoints[5], Dist_0_5)
1561   V3_EUKLIDNORM_OF_DIFF(MidPoints[1], MidPoints[3], Dist_1_3)
1562   V3_EUKLIDNORM_OF_DIFF(MidPoints[2], MidPoints[4], Dist_2_4)
1563 
1564   /* return best Refrule (shortest interior edge) */
1565   flags = (Dist_0_5 < Dist_1_3) ;
1566   flags |= ((Dist_1_3 < Dist_2_4) <<1) ;
1567   flags |= ((Dist_2_4 < Dist_0_5) <<2) ;
1568   assert(flags != 7);
1569 
1570   switch(flags)
1571   {
1572   case 0 :                                              /* Dist_0_5 = Dist_2_4 = Dist_1_3 */
1573     return (FULL_REFRULE_0_5);
1574   case 1 :                                              /* Dist_0_5 < Dist_2_4 < Dist_1_3 */
1575     return (FULL_REFRULE_0_5);
1576   case 2 :                                              /* Dist_1_3 < Dist_0_5 < Dist_2_4 */
1577     return (FULL_REFRULE_1_3);
1578   case 3 :                                              /* Dist_0_5 < Dist_1_3 < Dist_2_4 */
1579     return (FULL_REFRULE_0_5);
1580   case 4 :                                              /* Dist_2_4 < Dist_1_3 < Dist_0_5 */
1581     return (FULL_REFRULE_2_4);
1582   case 5 :                                              /* Dist_2_4 < Dist_0_5 < Dist_1_3 */
1583     return (FULL_REFRULE_2_4);
1584   case 6 :                                              /* Dist_1_3 < Dist_2_4 < Dist_0_5 */
1585     return (FULL_REFRULE_1_3);
1586   }
1587   return (-1);
1588 }
1589 
1590 
1591 #ifdef __ALLRULES__
1592 
1593 
1594 /****************************************************************************/
1595 /** \brief Compute best full refined refrule for the element
1596 
1597    \param theElement - for that element
1598 
1599    This function computes the best full refined refrule for the element
1600 
1601    \return
1602    Mark: number of refrule
1603  */
1604 /****************************************************************************/
1605 
MinimalSideAngle(ELEMENT * theElement)1606 static INT MinimalSideAngle (ELEMENT *theElement)
1607 {
1608   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1609   DOUBLE_VECTOR MidPoints[MAX_EDGES_OF_ELEM];
1610 
1611   /* get physical position of the corners */
1612   for (INT i=0; i<CORNERS_OF_ELEM(theElement); i++)
1613     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1614 
1615   /* get physical position of the midpoints of the edges */
1616   for (INT i=0; i<EDGES_OF_ELEM(theElement); i++)
1617     V3_LINCOMB(0.5, Corners[CORNER_OF_EDGE(theElement,i,0)], 0.5, Corners[CORNER_OF_EDGE(theElement,i,1)], MidPoints[i]);
1618 
1619   /* try possibilities */
1620   DOUBLE Min = 190.0;
1621   INT imin = 0;
1622   for (INT i=0; i<3; i++)
1623   {
1624     INT j = OPPOSITE_EDGE(theElement,i);
1625     Corners[2] = MidPoints[i];
1626     Corners[3] = MidPoints[j];
1627 
1628     DOUBLE Max = 0.0;
1629     for (INT k=0; k<2; k++)
1630     {
1631       DOUBLE MaxAngle;
1632       for (INT l=0; l<2; l++)
1633         Corners[l] = MidPoints[SideEdgesOfEdge[i][k][l]];
1634       if (TetMaxSideAngle(theElement,Corners,&MaxAngle))
1635         return (FULL_REFRULE_0_5);
1636       Max = MAX(Max,MaxAngle);
1637     }
1638     for (INT k=0; k<2; k++)
1639     {
1640       DOUBLE MaxAngle;
1641       for (INT l=0; l<2; l++)
1642         Corners[l] = MidPoints[SideEdgesOfEdge[j][k][l]];
1643       if (TetMaxSideAngle(theElement,Corners,&MaxAngle))
1644         return (FULL_REFRULE_0_5);
1645       Max = MAX(Max,MaxAngle);
1646     }
1647     if (Max<Min)
1648     {
1649       Min = Max;
1650       imin = i;
1651     }
1652   }
1653 
1654   switch (imin)
1655   {
1656   case 0 :
1657     return (FULL_REFRULE_0_5);
1658   case 1 :
1659     return (FULL_REFRULE_1_3);
1660   case 2 :
1661     return (FULL_REFRULE_2_4);
1662   }
1663 }
1664 
1665 
1666 /****************************************************************************/
1667 /** \brief Compute best full refined refrule for the element
1668 
1669    \param theElement - for that element
1670 
1671    This function computes the best full refined refrule for the element
1672 
1673    \return
1674    Mark: number of refrule
1675  */
1676 /****************************************************************************/
1677 
MinimalSideEntry(ELEMENT * theElement)1678 static INT MinimalSideEntry (ELEMENT *theElement)
1679 {
1680   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1681   DOUBLE_VECTOR MidPoints[MAX_EDGES_OF_ELEM];
1682   INT i,j,k,l,imin;
1683   DOUBLE Angle[MAX_EDGES_OF_ELEM],Length[MAX_EDGES_OF_ELEM],Max,Min,help;
1684 
1685   /* get physical position of the corners */
1686   for (i=0; i<CORNERS_OF_ELEM(theElement); i++)
1687     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1688 
1689   /* get physical position of the midpoints of the edges */
1690   for (i=0; i<EDGES_OF_ELEM(theElement); i++)
1691     V3_LINCOMB(0.5, Corners[CORNER_OF_EDGE(theElement,i,0)], 0.5, Corners[CORNER_OF_EDGE(theElement,i,1)], MidPoints[i]);
1692 
1693   /* try possibilities */
1694   Min = MAX_C;
1695   for (i=0; i<3; i++)
1696   {
1697     j = OPPOSITE_EDGE(theElement,i);
1698     Corners[2] = MidPoints[i];
1699     Corners[3] = MidPoints[j];
1700 
1701     Max = 0.0;
1702     for (k=0; k<2; k++)
1703     {
1704       for (l=0; l<2; l++)
1705         Corners[l] = MidPoints[SideEdgesOfEdge[i][k][l]];
1706       if (TetAngleAndLength(theElement,Corners,Angle,Length))
1707         return (FULL_REFRULE_0_5);
1708       for (l=0; l<EDGES_OF_ELEM(theElement); l++)
1709         if (Angle[l]>PI/2.0)
1710         {
1711           help = std::abs(Length[l]*(DOUBLE)(cos((double)Angle[l])/sin((double)Angle[l])));
1712           Max = MAX(Max,help);
1713         }
1714     }
1715     for (k=0; k<2; k++)
1716     {
1717       for (l=0; l<2; l++)
1718         Corners[l] = MidPoints[SideEdgesOfEdge[j][k][l]];
1719       if (TetAngleAndLength(theElement,Corners,Angle,Length))
1720         return (FULL_REFRULE_0_5);
1721       for (i=0; i<EDGES_OF_ELEM(theElement); i++)
1722         if (Angle[l]>PI/2.0)
1723         {
1724           help = std::abs(Length[l]*(DOUBLE)(cos((double)Angle[l])/sin((double)Angle[l])));
1725           Max = MAX(Max,help);
1726         }
1727     }
1728     if (Max<Min)
1729     {
1730       Min = Max;
1731       imin = i;
1732     }
1733   }
1734 
1735   switch (imin)
1736   {
1737   case 0 :
1738     return (FULL_REFRULE_0_5);
1739   case 1 :
1740     return (FULL_REFRULE_1_3);
1741   case 2 :
1742     return (FULL_REFRULE_2_4);
1743   }
1744 }
1745 
1746 
1747 /****************************************************************************/
1748 /** \brief Compute best full refined refrule for the element
1749 
1750    \param theElement - for that element
1751 
1752    This function computes the best full refined refrule for the element: optimal laplace-disc w.r.t. M-Matrix eigenschaft.
1753 
1754    \return
1755    Mark: number of refrule
1756  */
1757 /****************************************************************************/
1758 
BestLaplaceMMatrix(ELEMENT * theElement)1759 static INT BestLaplaceMMatrix (ELEMENT *theElement)
1760 {
1761   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1762   DOUBLE_VECTOR MidPoints[MAX_EDGES_OF_ELEM];
1763   INT i,j,k,l,imin,TBFR,refrule;
1764   DOUBLE Angle[MAX_EDGES_OF_ELEM],Length[MAX_EDGES_OF_ELEM],sum,Min;
1765 
1766   /* get physical position of the corners */
1767   for (i=0; i<CORNERS_OF_ELEM(theElement); i++)
1768     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1769 
1770   /* get physical position of the midpoints of the edges */
1771   for (i=0; i<EDGES_OF_ELEM(theElement); i++)
1772     V3_LINCOMB(0.5, Corners[CORNER_OF_EDGE(theElement,i,0)], 0.5, Corners[CORNER_OF_EDGE(theElement,i,1)], MidPoints[i]);
1773 
1774   /* try possebilities */
1775   Min = MAX_C; imin = -1;
1776   for (i=0; i<3; i++)
1777   {
1778     j = OPPOSITE_EDGE(theElement,i);
1779     Corners[2] = MidPoints[i];
1780     Corners[3] = MidPoints[j];
1781 
1782     sum = 0.0;
1783     for (k=0; k<2; k++)
1784     {
1785       for (l=0; l<2; l++)
1786         Corners[l] = MidPoints[SideEdgesOfEdge[i][k][l]];
1787       if (TetAngleAndLength(theElement,Corners,Angle,Length))
1788         return (FULL_REFRULE_0_5);
1789       for (l=0; l<EDGES_OF_ELEM(theElement); l++)
1790         if (Angle[l]>PI/2.0)
1791           sum += std::abs(Length[l]*(DOUBLE)cos((double)Angle[l])/(DOUBLE)sin((double)Angle[l]));
1792     }
1793     for (k=0; k<2; k++)
1794     {
1795       for (l=0; l<2; l++)
1796         Corners[l] = MidPoints[SideEdgesOfEdge[j][k][l]];
1797       if (TetAngleAndLength(theElement,Corners,Angle,Length))
1798         return (FULL_REFRULE_0_5);
1799       for (i=0; i<EDGES_OF_ELEM(theElement); i++)
1800         if (Angle[l]>PI/2.0)
1801           sum += std::abs(Length[l]*(DOUBLE)cos((double)Angle[l])/(DOUBLE)sin((double)Angle[l]));
1802     }
1803     if (sum<Min)
1804     {
1805       Min = sum;
1806       imin = i;
1807     }
1808   }
1809 
1810   switch (imin)
1811   {
1812   case 0 :
1813     refrule = FULL_REFRULE_0_5;
1814     break;
1815   case 1 :
1816     refrule = FULL_REFRULE_1_3;
1817     break;
1818   case 2 :
1819     refrule = FULL_REFRULE_2_4;
1820     break;
1821   }
1822 
1823 
1824   TBFR = ShortestInteriorEdge(theElement);
1825   if (imin == -1)
1826   {
1827     refrule = TBFR;
1828     UserWrite ("#");
1829   }
1830 
1831   return (refrule);
1832 }
1833 
1834 #endif
1835 
1836 
1837 /****************************************************************************/
1838 /** \brief Compute best full refined refrule for the element
1839 
1840    \param theElement - for that element
1841 
1842    This function computes the best full refined refrule for the element: optimal laplace-disc w.r.t. M-Matrix eigenschaft
1843 
1844    \return
1845    .n   Mark: number of refrule
1846  */
1847 /****************************************************************************/
1848 
MaxPerpendicular(ELEMENT * theElement)1849 static INT MaxPerpendicular (ELEMENT *theElement)
1850 {
1851   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1852   DOUBLE_VECTOR MidPoints[MAX_EDGES_OF_ELEM];
1853 
1854   /* get physical position of the corners */
1855   for (INT i=0; i<CORNERS_OF_ELEM(theElement); i++)
1856     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1857 
1858   /* get physical position of the midpoints of the edges */
1859   for (INT i=0; i<EDGES_OF_ELEM(theElement); i++)
1860     V3_LINCOMB(0.5, Corners[CORNER_OF_EDGE(theElement,i,0)], 0.5, Corners[CORNER_OF_EDGE(theElement,i,1)], MidPoints[i]);
1861 
1862   /* try possibilities */
1863   DOUBLE Max = -MAX_C;
1864   INT imin = -1;
1865   for (INT i=0; i<3; i++)
1866   {
1867     DOUBLE_VECTOR a,b,c;
1868     DOUBLE sprd;
1869     INT j = OPPOSITE_EDGE(theElement,i);
1870 
1871     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,i,0)],Corners[CORNER_OF_EDGE(theElement,i,1)],a)
1872     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,j,0)],Corners[CORNER_OF_EDGE(theElement,j,1)],b)
1873     V3_VECTOR_PRODUCT(a,b,c)
1874     V3_Normalize(c);
1875     V3_SUBTRACT(MidPoints[i],MidPoints[j],a)
1876     V3_Normalize(a);
1877     V3_SCALAR_PRODUCT(a,c,sprd)
1878     sprd = std::abs(sprd);
1879 
1880     if (sprd>Max)
1881     {
1882       Max = sprd;
1883       imin = i;
1884     }
1885   }
1886 
1887   INT refrule;
1888   switch (imin)
1889   {
1890   case -1 :
1891     refrule = ShortestInteriorEdge (theElement);
1892     UserWrite ("#");
1893     break;
1894   case 0 :
1895     refrule = FULL_REFRULE_0_5;
1896     break;
1897   case 1 :
1898     refrule = FULL_REFRULE_1_3;
1899     break;
1900   case 2 :
1901     refrule = FULL_REFRULE_2_4;
1902     break;
1903   }
1904 
1905   return (refrule);
1906 }
1907 
1908 
1909 /****************************************************************************/
1910 /** \brief
1911    MaxRightAngle - compute best full refined refrule for the element
1912 
1913    SYNOPSIS:
1914    static INT MaxRightAngle (ELEMENT *theElement);
1915 
1916    PARAMETERS:
1917    \param theElement - for that element
1918 
1919    DESCRIPTION:
1920    This function computes the best full refined refrule for the element: optimal laplace-disc w.r.t. M-Matrix eigenschaft
1921 
1922    \return
1923    INT
1924    .n   Mark: number of refrule
1925  */
1926 /****************************************************************************/
1927 
MaxRightAngle(ELEMENT * theElement)1928 static INT MaxRightAngle (ELEMENT *theElement)
1929 {
1930   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
1931 
1932   /* get physical position of the corners */
1933   for (INT i=0; i<CORNERS_OF_ELEM(theElement); i++)
1934     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
1935 
1936   /* try possibilities */
1937   DOUBLE Min = MAX_C;
1938   INT imin = -1;
1939   for (INT i=0; i<3; i++)
1940   {
1941     DOUBLE_VECTOR a,b;
1942     DOUBLE sprd;
1943     INT j = OPPOSITE_EDGE(theElement,i);
1944 
1945     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,i,0)],Corners[CORNER_OF_EDGE(theElement,i,1)],a)
1946     V3_Normalize(a);
1947     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,j,0)],Corners[CORNER_OF_EDGE(theElement,j,1)],b)
1948     V3_Normalize(b);
1949     V3_SCALAR_PRODUCT(a,b,sprd)
1950     sprd = std::abs(sprd);
1951 
1952     if (sprd<Min)
1953     {
1954       Min = sprd;
1955       imin = i;
1956     }
1957   }
1958 
1959   INT refrule;
1960   switch (imin)
1961   {
1962   case -1 :
1963     refrule = ShortestInteriorEdge (theElement);
1964     UserWrite ("#");
1965     break;
1966   case 0 :
1967     refrule = FULL_REFRULE_0_5;
1968     break;
1969   case 1 :
1970     refrule = FULL_REFRULE_1_3;
1971     break;
1972   case 2 :
1973     refrule = FULL_REFRULE_2_4;
1974     break;
1975   }
1976 
1977   return (refrule);
1978 }
1979 
1980 
1981 /****************************************************************************/
1982 /** \brief
1983    MaxArea - compute best full refined refrule for the element
1984 
1985    SYNOPSIS:
1986    static INT MaxArea (ELEMENT *theElement);
1987 
1988    PARAMETERS:
1989    \param theElement - for that element
1990 
1991    DESCRIPTION:
1992    This function computes the best full refined refrule for the element: optimal laplace-disc w.r.t. M-Matrix eigenschaft
1993 
1994    \return
1995    INT
1996    .n   Mark: number of refrule
1997  */
1998 /****************************************************************************/
1999 
MaxArea(ELEMENT * theElement)2000 static INT MaxArea (ELEMENT *theElement)
2001 {
2002   DOUBLE *Corners[MAX_CORNERS_OF_ELEM];
2003 
2004   /* get physical position of the corners */
2005   for (INT i=0; i<CORNERS_OF_ELEM(theElement); i++)
2006     Corners[i] = CVECT(MYVERTEX(CORNER(theElement,i)));
2007 
2008   /* try possebilities */
2009   DOUBLE Max = -MAX_C;
2010   INT imin = -1;
2011   for (INT i=0; i<3; i++)
2012   {
2013     DOUBLE_VECTOR a,b,c;
2014     DOUBLE norm;
2015     INT j = OPPOSITE_EDGE(theElement,i);
2016 
2017     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,i,0)],Corners[CORNER_OF_EDGE(theElement,i,1)],a)
2018     V3_SUBTRACT(Corners[CORNER_OF_EDGE(theElement,j,0)],Corners[CORNER_OF_EDGE(theElement,j,1)],b)
2019     V3_VECTOR_PRODUCT(a,b,c)
2020     V3_EUKLIDNORM(c,norm)
2021 
2022     if (norm>Max)
2023     {
2024       Max = norm;
2025       imin = i;
2026     }
2027   }
2028 
2029   INT refrule;
2030   switch (imin)
2031   {
2032   case -1 :
2033     refrule = ShortestInteriorEdge (theElement);
2034     UserWrite ("#");
2035     break;
2036   case 0 :
2037     refrule = FULL_REFRULE_0_5;
2038     break;
2039   case 1 :
2040     refrule = FULL_REFRULE_1_3;
2041     break;
2042   case 2 :
2043     refrule = FULL_REFRULE_2_4;
2044     break;
2045   }
2046 
2047   return (refrule);
2048 }
2049 
2050 #endif /* __THREEDIM__ */
2051 
2052 
2053 /****************************************************************************/
2054 /** \brief Mark an element for refinement
2055 
2056    \param theElement - Element to be refined
2057    \param rule - type of refinement mark
2058 
2059    This function marks an element for refinement
2060 
2061    \return <ul>
2062    <li> 1 if element has been marked </li>
2063    <li> 0 if element cannot be marked </li>
2064    </ul>
2065  */
2066 /****************************************************************************/
2067 
MarkForRefinement(ELEMENT * theElement,enum RefinementRule rule,INT side)2068 INT NS_DIM_PREFIX MarkForRefinement (ELEMENT *theElement, enum RefinementRule rule, INT side)
2069 {
2070   if (theElement == NULL) return(0);
2071         #ifdef ModelP
2072   if (EGHOST(theElement)) return(0);
2073         #endif
2074 
2075   SETCOARSEN(theElement,0);
2076 
2077   if (rule != COARSE)
2078     theElement = ELEMENT_TO_MARK(theElement);
2079   ASSERT(theElement!=NULL);
2080 
2081   PRINTDEBUG(gm,4,("MarkForRefinement() e=" EID_FMTX "rule=%d\n",
2082                    EID_PRTX(theElement),rule))
2083 
2084   /* choose dimension */
2085   switch (DIM)
2086   {
2087                 #ifdef __TWODIM__
2088   /* 2D case */
2089   case (2) :
2090 
2091     switch (TAG(theElement))
2092     {
2093     case (TRIANGLE) :
2094       switch (rule)
2095       {
2096       case COARSE :
2097         SETCOARSEN(theElement,1);
2098         SETMARK(theElement,NO_REFINEMENT);
2099         SETMARKCLASS(theElement,0);
2100         break;
2101 
2102       case NO_REFINEMENT :
2103         SETMARK(theElement,NO_REFINEMENT);
2104         SETMARKCLASS(theElement,0);
2105         break;
2106 
2107       case COPY :
2108         SETMARK(theElement,T_COPY);
2109         SETMARKCLASS(theElement,RED_CLASS);
2110         break;
2111 
2112       case RED :
2113         SETMARK(theElement,T_RED);
2114         SETMARKCLASS(theElement,RED_CLASS);
2115         break;
2116 
2117       /* TODO: these marks must be introduced first
2118          case BISECTION_3:
2119               if (side<0) return (GM_ERROR);
2120               SETMARK(theElement,TRI_BISECT_3+side%3);
2121               SETMARKCLASS(theElement,RED_CLASS);
2122               break;
2123 
2124          case BISECTION_1:
2125               if (side<0) return (GM_ERROR);
2126               SETMARK(theElement,TRI_BISECT_1+side%3);
2127               SETMARKCLASS(theElement,RED_CLASS);
2128               break;
2129 
2130          case BISECTION_2_Q:
2131               if (side<0) return (GM_ERROR);
2132               SETMARK(theElement,TRI_BISECT_2_Q+side%3);
2133               SETMARKCLASS(theElement,RED_CLASS);
2134               break;
2135 
2136          case BISECTION_2_T1:
2137               if (side<0) return (GM_ERROR);
2138               SETMARK(theElement,TRI_BISECT_2_T1+side%3);
2139               SETMARKCLASS(theElement,RED_CLASS);
2140               break;
2141 
2142          case BISECTION_2_T2:
2143               if (side<0) return (GM_ERROR);
2144               SETMARK(theElement,TRI_BISECT_2_T2+side%3);
2145               SETMARKCLASS(theElement,RED_CLASS);
2146               break;
2147        */
2148 
2149       default :
2150         return(GM_ERROR);
2151       }
2152       break;
2153 
2154     case (QUADRILATERAL) :
2155       switch (rule)
2156       {
2157       case COARSE :
2158         SETCOARSEN(theElement,1);
2159         SETMARKCLASS(theElement,0);
2160         SETMARK(theElement,NO_REFINEMENT);
2161         break;
2162 
2163       case NO_REFINEMENT :
2164         SETMARK(theElement,NO_REFINEMENT);
2165         SETMARKCLASS(theElement,0);
2166         break;
2167 
2168       case COPY :
2169         SETMARK(theElement,Q_COPY);
2170         SETMARKCLASS(theElement,RED_CLASS);
2171         break;
2172 
2173       case RED :
2174         SETMARK(theElement,Q_RED);
2175         SETMARKCLASS(theElement,RED_CLASS);
2176         break;
2177 
2178       /* TODO: these mark must be introduced first */
2179       case BLUE :
2180         if (side<0) return (GM_ERROR);
2181         if (side%2 == 0)
2182           SETMARK(theElement,Q_BLUE_0);
2183         else
2184           SETMARK(theElement,Q_BLUE_1);
2185         SETMARKCLASS(theElement,RED_CLASS);
2186         break;
2187 
2188       default :
2189         return(GM_ERROR);
2190       }
2191       break;
2192 
2193     default :
2194       return(GM_ERROR);
2195     }
2196     break;
2197                         #endif /* __TWODIM__ */
2198 
2199 
2200                 #ifdef __THREEDIM__
2201   /* 3D case */
2202   case (3) :
2203     switch (TAG(theElement))
2204     {
2205     case (TETRAHEDRON) :
2206       switch(rule)
2207       {
2208       case (COARSE) :
2209         SETMARK(theElement,NO_REFINEMENT);
2210         SETMARKCLASS(theElement,0);
2211         SETCOARSEN(theElement,1);
2212         break;
2213       case (NO_REFINEMENT) :
2214         SETMARK(theElement,NO_REFINEMENT);
2215         SETMARKCLASS(theElement,0);
2216         break;
2217       case (COPY) :
2218         SETMARK(theElement,TET_COPY);
2219         SETMARKCLASS(theElement,RED_CLASS);
2220         break;
2221       case (RED) :
2222         SETMARK(theElement,(*theFullRefRule)(theElement));
2223         SETMARKCLASS(theElement,RED_CLASS);
2224         break;
2225 #ifndef DUNE_UGGRID_TET_RULESET
2226       case (TETRA_RED_HEX) :
2227         SETMARK(theElement,TET_RED_HEX);
2228         SETMARKCLASS(theElement,RED_CLASS);
2229         break;
2230 #endif
2231       default :
2232         return(GM_ERROR);
2233       }
2234       break;
2235 
2236     case (PYRAMID) :
2237       switch(rule)
2238       {
2239       case (COARSE) :
2240         SETMARK(theElement,NO_REFINEMENT);
2241         SETMARKCLASS(theElement,0);
2242         SETCOARSEN(theElement,1);
2243         break;
2244       case (NO_REFINEMENT) :
2245         SETMARK(theElement,NO_REFINEMENT);
2246         SETMARKCLASS(theElement,0);
2247         break;
2248       case (COPY) :
2249         SETMARK(theElement,PYR_COPY);
2250         SETMARKCLASS(theElement,RED_CLASS);
2251         break;
2252       case (RED) :
2253         SETMARK(theElement,PYR_RED);
2254         SETMARKCLASS(theElement,RED_CLASS);
2255         break;
2256       default :
2257         return(GM_ERROR);
2258       }
2259       break;
2260 
2261     case (PRISM) :
2262       switch(rule)
2263       {
2264       case (COARSE) :
2265         SETMARK(theElement,NO_REFINEMENT);
2266         SETMARKCLASS(theElement,0);
2267         SETCOARSEN(theElement,1);
2268         break;
2269       case (NO_REFINEMENT) :
2270         SETMARK(theElement,NO_REFINEMENT);
2271         SETMARKCLASS(theElement,0);
2272         break;
2273       case (COPY) :
2274         SETMARK(theElement,PRI_COPY);
2275         SETMARKCLASS(theElement,RED_CLASS);
2276         break;
2277       case (RED) :
2278         SETMARKCLASS(theElement,RED_CLASS);
2279 
2280                                                         #ifdef __ANISOTROPIC__
2281         {
2282           INT newrule;
2283 
2284           if (GetRule_AnisotropicRed(theElement,&newrule))
2285           {
2286             SETMARK(theElement,newrule);
2287             break;
2288           }
2289         }
2290                                                         #endif
2291 
2292         SETMARK(theElement,PRI_RED);
2293         break;
2294       case (PRISM_BISECT_1_2) :
2295         SETMARK(theElement,PRI_BISECT_1_2);
2296         SETMARKCLASS(theElement,RED_CLASS);
2297         break;
2298       case (PRISM_QUADSECT) :
2299         SETMARK(theElement,PRI_QUADSECT);
2300         SETMARKCLASS(theElement,RED_CLASS);
2301         break;
2302       case (PRISM_BISECT_HEX0) :
2303         SETMARK(theElement,PRI_BISECT_HEX0);
2304         SETMARKCLASS(theElement,RED_CLASS);
2305         break;
2306       case (PRISM_BISECT_HEX1) :
2307         SETMARK(theElement,PRI_BISECT_HEX1);
2308         SETMARKCLASS(theElement,RED_CLASS);
2309         break;
2310       case (PRISM_BISECT_HEX2) :
2311         SETMARK(theElement,PRI_BISECT_HEX2);
2312         SETMARKCLASS(theElement,RED_CLASS);
2313         break;
2314       case (PRISM_ROTATE_LEFT) :
2315         SETMARK(theElement,PRI_ROT_L);
2316         SETMARKCLASS(theElement,RED_CLASS);
2317         break;
2318       case (PRISM_ROTATE_RGHT) :
2319         SETMARK(theElement,PRI_ROT_R);
2320         SETMARKCLASS(theElement,RED_CLASS);
2321         break;
2322       case (PRISM_QUADSECT_HEXPRI0) :
2323         SETMARK(theElement,PRI_QUADSECT_HEXPRI0);
2324         SETMARKCLASS(theElement,RED_CLASS);
2325         break;
2326       case (PRISM_BISECT_0_1) :
2327         SETMARK(theElement,PRI_BISECT_0_1);
2328         SETMARKCLASS(theElement,RED_CLASS);
2329         break;
2330       case (PRISM_BISECT_0_2) :
2331         SETMARK(theElement,PRI_BISECT_0_2);
2332         SETMARKCLASS(theElement,RED_CLASS);
2333         break;
2334       case (PRISM_BISECT_0_3) :
2335         SETMARK(theElement,PRI_BISECT_0_3);
2336         SETMARKCLASS(theElement,RED_CLASS);
2337         break;
2338 
2339       default :
2340         return(GM_ERROR);
2341       }
2342       break;
2343 
2344     case (HEXAHEDRON) :
2345       switch(rule)
2346       {
2347       case (COARSE) :
2348         SETMARK(theElement,NO_REFINEMENT);
2349         SETMARKCLASS(theElement,0);
2350         SETCOARSEN(theElement,1);
2351         break;
2352       case (NO_REFINEMENT) :
2353         SETMARK(theElement,NO_REFINEMENT);
2354         SETMARKCLASS(theElement,0);
2355         break;
2356       case (COPY) :
2357         SETMARK(theElement,HEXA_COPY);
2358         SETMARKCLASS(theElement,RED_CLASS);
2359         break;
2360       case (RED) :
2361         SETMARK(theElement,HEXA_RED);
2362         SETMARKCLASS(theElement,RED_CLASS);
2363         break;
2364       case (HEX_BISECT_0_1) :
2365         SETMARK(theElement,HEXA_BISECT_0_1);
2366         SETMARKCLASS(theElement,RED_CLASS);
2367         break;
2368       case (HEX_BISECT_0_2) :
2369         SETMARK(theElement,HEXA_BISECT_0_2);
2370         SETMARKCLASS(theElement,RED_CLASS);
2371         break;
2372       case (HEX_BISECT_0_3) :
2373         SETMARK(theElement,HEXA_BISECT_0_3);
2374         SETMARKCLASS(theElement,RED_CLASS);
2375         break;
2376       case (HEX_TRISECT_0) :
2377         SETMARK(theElement,HEXA_TRISECT_0);
2378         SETMARKCLASS(theElement,RED_CLASS);
2379         break;
2380       case (HEX_TRISECT_5) :
2381         SETMARK(theElement,HEXA_TRISECT_5);
2382         SETMARKCLASS(theElement,RED_CLASS);
2383         break;
2384       case (HEX_QUADSECT_0) :
2385         SETMARK(theElement,HEXA_QUADSECT_0);
2386         SETMARKCLASS(theElement,RED_CLASS);
2387         break;
2388       case (HEX_QUADSECT_1) :
2389         SETMARK(theElement,HEXA_QUADSECT_1);
2390         SETMARKCLASS(theElement,RED_CLASS);
2391         break;
2392       case (HEX_QUADSECT_2) :
2393         SETMARK(theElement,HEXA_QUADSECT_2);
2394         SETMARKCLASS(theElement,RED_CLASS);
2395         break;
2396       case (HEX_BISECT_HEXPRI0) :
2397         SETMARK(theElement,HEXA_BISECT_HEXPRI0);
2398         SETMARKCLASS(theElement,RED_CLASS);
2399         break;
2400       case (HEX_BISECT_HEXPRI1) :
2401         SETMARK(theElement,HEXA_BISECT_HEXPRI1);
2402         SETMARKCLASS(theElement,RED_CLASS);
2403         break;
2404       default :
2405         return(GM_ERROR);
2406       }
2407       break;
2408 
2409     default :
2410       return(GM_ERROR);
2411     }
2412     break;
2413                         #endif /* __THREEDIM__ */
2414 
2415   default :
2416     return(GM_ERROR);
2417   }
2418 
2419   return(GM_OK);
2420 }
2421 
2422 /****************************************************************************/
2423 /** \brief Return true when element can be tagged for refinement
2424 
2425    \param theElement - element to refine
2426 
2427    This function returns true (1) when element can be tagged for refinement
2428 
2429    \return <ul>
2430    <li> false - do not tag element </li>
2431    <li> true - element can be tagged for refinement </li>
2432    </ul>
2433  */
2434 /****************************************************************************/
2435 
EstimateHere(const ELEMENT * theElement)2436 INT NS_DIM_PREFIX EstimateHere (const ELEMENT *theElement)
2437 {
2438         #ifdef ModelP
2439   if (EGHOST(theElement)) return(0);
2440         #endif
2441   return(LEAFELEM(theElement));
2442 }
2443 
2444 
2445 /****************************************************************************/
2446 /** \brief Return mark of rule for a specific pattern
2447 
2448    \param theElement - element rule is searched for
2449    \param pattern: pattern a rule is searched for
2450 
2451    This function returns mark of rule for a specific pattern
2452 
2453    \return Mark rule; values of the unnamed enums in the file rm.h
2454    mark of rule
2455  */
2456 /****************************************************************************/
2457 
Patterns2Rules(ELEMENT * theElement,INT pattern)2458 INT NS_DIM_PREFIX Patterns2Rules(ELEMENT *theElement, INT pattern)
2459 {
2460         #ifdef __TWODIM__
2461   switch (TAG(theElement)) {
2462   case (TRIANGLE) :
2463     switch (pattern) {
2464     /** \todo 0 can mean T_COPY OR T_NOREF */
2465     case (0) : return(T_NOREF);
2466     case (1) : return(T_BISECT_1_0);
2467     case (2) : return(T_BISECT_1_1);
2468     case (3) : return(T_BISECT_2_T1_2);
2469     case (4) : return(T_BISECT_1_2);
2470     case (5) : return(T_BISECT_2_T1_1);
2471     case (6) : return(T_BISECT_2_T1_0);
2472     case (7) : return(T_RED);
2473     default :
2474       assert(0);
2475       PrintErrorMessage('E',"Patterns2Rules","no mapping for TRIANGLE and this pattern!");
2476       return(-1);
2477     }
2478     break;
2479   case (QUADRILATERAL) :
2480     switch (pattern) {
2481     /** \todo 0 can mean Q_COPY OR Q_NOREF */
2482     case (0) : return(Q_NOREF);
2483     case (5) : return(Q_BLUE_0);
2484     case (7) : return(Q_CLOSE_3_3);
2485     case (10) : return(Q_BLUE_1);
2486     case (11) : return(Q_CLOSE_3_2);
2487     case (13) : return(Q_CLOSE_3_1);
2488     case (14) : return(Q_CLOSE_3_0);
2489 
2490     case (1) :                                    /* mapping for green closure */
2491     case (17) : return(Q_CLOSE_2_0);
2492 
2493     case (2) :                                    /* mapping for green closure */
2494     case (18) : return(Q_CLOSE_2_1);
2495 
2496     case (3) :                                    /* mapping for green closure */
2497     case (19) : return(Q_CLOSE_1_0);
2498 
2499     case (4) :                                    /* mapping for green closure */
2500     case (20) : return(Q_CLOSE_2_2);
2501 
2502     case (6) :                                    /* mapping for green closure */
2503     case (22) : return(Q_CLOSE_1_1);
2504 
2505     case (8) :                                    /* mapping for green closure */
2506     case (24) : return(Q_CLOSE_2_3);
2507 
2508     case (9) :                                    /* mapping for green closure */
2509     case (25) : return(Q_CLOSE_1_3);
2510 
2511     case (12) :                                    /* mapping for green closure */
2512     case (28) : return(Q_CLOSE_1_2);
2513 
2514     case (15) :                                    /* mapping for green closure */
2515     case (31) : return(Q_RED);
2516     default :
2517       assert(0);
2518       PrintErrorMessage('E',"Patterns2Rules","no mapping for QUADRILATERAL and this pattern!");
2519       return(-1);
2520     }
2521     break;
2522   default :
2523     PrintErrorMessage('E',"Patterns2Rules","Elementtype not found!");
2524     assert(0); return(-1);
2525   }
2526         #endif
2527         #ifdef __THREEDIM__
2528   switch (TAG(theElement)) {
2529   case (TETRAHEDRON) :
2530 #ifdef DUNE_UGGRID_TET_RULESET
2531     /* convert pattern to old style */
2532     pattern &= (~(1<<10));
2533 
2534     IFDEBUG(gm,0)
2535     int tetrarule;
2536     if (pattern<0 || pattern>1023)
2537       PRINTDEBUG(gm,0,("Pattern2Rule(): ERROR elem=" EID_FMTX
2538                        " pattern=%d\n",EID_PRTX(theElement),pattern))
2539       assert(pattern>=0 && pattern<=1023);
2540     tetrarule = Pattern2Rule[TAG(theElement)][pattern];
2541     if (tetrarule<0 || tetrarule>MaxRules[TETRAHEDRON])
2542       PRINTDEBUG(gm,0,("Pattern2Rule(): ERROR elem=" EID_FMTX
2543                        " pattern=%d rule=%d\n",EID_PRTX(theElement),pattern,tetrarule))
2544       assert(tetrarule>=0 && tetrarule<=MaxRules[TETRAHEDRON]);
2545     ENDDEBUG
2546 
2547     return(Pattern2Rule[TAG(theElement)][pattern]);
2548 #else
2549     if (MARKCLASS(theElement) != RED_CLASS) return(0);
2550     switch (pattern) {
2551     /* copy rule */
2552     case (0) :
2553       return(0);
2554     case (63) :
2555       return(TET_RED);
2556     case (1023) :
2557       return(TET_RED_HEX);
2558     default :
2559       PrintErrorMessage('E',"Patterns2Rules","no mapping for TETRAHEDRON and this pattern!");
2560       assert(0); return(-1);
2561     }
2562     break;
2563 #endif
2564 
2565   case (PYRAMID) :
2566     if (MARKCLASS(theElement) != RED_CLASS) return(0);
2567     switch (pattern) {
2568     /* copy rule */
2569     case (0) :
2570       return(0);
2571     case (511) :
2572       return(PYR_RED);
2573     default :
2574       PrintErrorMessage('E',"Patterns2Rules","no mapping for PYRAMID and this pattern!");
2575       assert(0); return(-1);
2576     }
2577     break;
2578 
2579   case (PRISM) :
2580     if (MARKCLASS(theElement) != RED_CLASS) return(0);
2581     switch (pattern) {
2582     /* copy rule */
2583     case (0) :
2584       return(0);
2585     case (7679) :
2586       return(PRI_RED);
2587     case (455) :
2588       return(PRI_QUADSECT);
2589     case 56 :
2590       return PRI_BISECT_1_2;
2591     case 65 :
2592       return PRI_BISECT_0_1;
2593     case 130 :
2594       return PRI_BISECT_0_2;
2595     case 260 :
2596       return PRI_BISECT_0_3;
2597     case 325 :
2598       return PRI_BISECT_HEX0;
2599     case 195 :
2600       return PRI_BISECT_HEX1;
2601     case 390 :
2602       return PRI_BISECT_HEX2;
2603     default :
2604       PrintErrorMessageF('E',"Patterns2Rules","no mapping for PRISM and pattern %d!", pattern);
2605                                                 #ifndef __ANISOTROPIC__
2606       assert(0);
2607                                                 #endif
2608       return(-1);
2609     }
2610     break;
2611 
2612   case (HEXAHEDRON) :
2613     if (MARKCLASS(theElement) != RED_CLASS) return(0);
2614     switch (pattern) {
2615     /* copy rule */
2616     case (0) :
2617       return(0);
2618     /* full red rule */
2619     case (262143) :
2620       return(HEXA_RED);
2621     case (1285) :
2622       return HEXA_BISECT_0_1;
2623     case (2570) :
2624       return HEXA_BISECT_0_2;
2625     case (240) :
2626       return HEXA_BISECT_0_3;
2627     case (139023) :
2628       return HEXA_QUADSECT_0;
2629     case (42485) :
2630       return HEXA_QUADSECT_1;
2631     case (84730) :
2632       return HEXA_QUADSECT_2;
2633     case (5) :
2634       return HEXA_TRISECT_0;
2635     case (1280) :
2636       return HEXA_TRISECT_5;
2637     case (2056) :
2638       return HEXA_BISECT_HEXPRI0;
2639     case (257) :
2640       return HEXA_BISECT_HEXPRI1;
2641     default :
2642       PrintErrorMessage('E',"Patterns2Rules","no mapping for HEXAHEDRON and this pattern!");
2643       UserWriteF("pattern=%d\n",pattern);
2644       assert(0); return(-1);
2645     }
2646     break;
2647 
2648   default :
2649     PrintErrorMessage('E',"Patterns2Rules","Elementtype not found!");
2650     assert(0); return(-1);
2651   }
2652         #endif
2653   PrintErrorMessage('E',"Patterns2Rules","Elementtype not found!");
2654   assert(0); return(-1);
2655 }
2656 
2657 /****************************************************************************/
2658 /** \brief Gets the element which has to be marked
2659 
2660    \param MarkElement - element to be estimated
2661 
2662    This function gets the element which has to be marked
2663 
2664    \return <ul>
2665    <li> first element downward with class RED_CLASS </li>
2666    <li> NULL if MarkElement was no surface element </li>
2667    </ul>
2668  */
2669 /****************************************************************************/
2670 
ELEMENT_TO_MARK(ELEMENT * theElement)2671 ELEMENT * NS_DIM_PREFIX ELEMENT_TO_MARK (ELEMENT *theElement)
2672 {
2673   if (IS_REFINED(theElement)) return(NULL);
2674 
2675   PRINTDEBUG(gm,4,("ELEMENT_TO_MARK() called for e=" EID_FMTX "\n",
2676                    EID_PRTX(theElement)))
2677 
2678   while (ECLASS(theElement) != RED_CLASS)
2679   {
2680     theElement = EFATHER(theElement);
2681     ASSERT(theElement != NULL);
2682   }
2683 
2684   return(theElement);
2685 }
2686 
2687 
2688 /****************************************************************************/
2689 /** \brief Gets rule of refinement
2690 
2691    \param theElement - element to refine
2692    \param rule - filled with current refinement rule
2693    \param data - filled with side, if rule is oriented
2694 
2695    This function gets rule of refinement
2696 
2697    \return
2698    .n   0: side information valid
2699    .n   1: rule without orientation
2700  */
2701 /****************************************************************************/
2702 
GetRefinementMark(ELEMENT * theElement,INT * rule,void * data)2703 INT NS_DIM_PREFIX GetRefinementMark (ELEMENT *theElement, INT *rule, void *data)
2704 {
2705   INT *side = (INT*)data;
2706   INT mark;
2707 
2708   if (LEAFELEM(theElement) &&
2709       ECLASS(theElement) != RED_CLASS)
2710     theElement = ELEMENT_TO_MARK(theElement);
2711 
2712   ASSERT(theElement != NULL);
2713   if (!((ECLASS(theElement) == RED_CLASS)
2714         && (REFINECLASS(theElement) != RED_CLASS)))
2715   {
2716     printf("GetRefinementMark: eclass=%d refineclass=%d\n",
2717            ECLASS(theElement),REFINECLASS(theElement));
2718     return(-1);
2719   }
2720 
2721   mark = MARK(theElement);
2722 
2723         #if defined(__THREEDIM__)
2724   /* tetrahedra have three red rules */
2725   if (TAG(theElement)==TETRAHEDRON &&
2726       (mark==TET_RED_2_4 || mark==TET_RED_0_5 || mark==TET_RED_1_3))
2727   {
2728     *rule=RED;
2729     return(GM_RULE_WITHOUT_ORIENTATION);
2730   }
2731         #endif
2732 
2733   switch (mark)
2734   {
2735   case RED :
2736     *rule=RED;
2737     break;
2738 #ifdef __TWODIM__
2739   case Q_BLUE_0 :
2740     *rule = BLUE;
2741     break;
2742   case Q_BLUE_1 :
2743     *rule = BLUE;
2744     break;
2745 #endif
2746   case NO_REFINEMENT :
2747     *rule=NO_REFINEMENT;
2748     if (COARSEN(theElement)) *rule = COARSE;
2749     break;
2750   case COPY :
2751     *rule=COPY; break;
2752   default :
2753     *rule=NO_REFINEMENT;  break;
2754   }
2755   *side=0;
2756   return(GM_RULE_WITHOUT_ORIENTATION);
2757 }
2758 
2759 
2760 /****************************************************************************/
2761 /** \brief
2762    GetRefinementMarkType - gets type of mark for an element
2763 
2764    SYNOPSIS:
2765    INT GetRefinementMarkType (ELEMENT *theElement);
2766 
2767    PARAMETERS:
2768    \param theElement - element to refine
2769 
2770    DESCRIPTION:
2771    This function gets the type of mark for an element
2772 
2773    \return
2774    INT
2775    .n   0 if element is not marked
2776    .n   1 if element is marked for refinement
2777    .n   -1 if element is marked for coarsening
2778  */
2779 /****************************************************************************/
2780 
GetRefinementMarkType(ELEMENT * theElement)2781 INT NS_DIM_PREFIX GetRefinementMarkType (ELEMENT *theElement)
2782 {
2783   INT rule;
2784   INT side;
2785 
2786   if (GetRefinementMark(theElement,&rule,&side) == -1) RETURN(GM_ERROR);
2787 
2788   switch (rule)
2789   {
2790   case RED :
2791 #ifdef __TWODIM__
2792   case BLUE :
2793 #endif
2794     return(1);
2795   case COPY :
2796   case NO_REFINEMENT :     return(0);
2797   case COARSE :            return(-1);
2798   default :                        assert(0);
2799   }
2800 
2801   return(0);
2802 }
2803 
2804 /****************************************************************************/
2805 /*
2806    PrintSonData -
2807 
2808    SYNOPSIS:
2809    static INT PrintSonData(struct sondata theSonData);
2810 
2811    PARAMETERS:
2812    \param theSonData
2813 
2814    DESCRIPTION:
2815 
2816    \return
2817    INT
2818  */
2819 /****************************************************************************/
2820 
PrintSonData(struct sondata theSonData,PrintfProcPtr Printf)2821 static INT PrintSonData (struct sondata theSonData, PrintfProcPtr Printf)
2822 {
2823   char buffer[128];
2824   int i,j;
2825   int path = theSonData.path;
2826   int pd = PATHDEPTH(path);
2827 
2828   Printf("tag=%d ",(int)theSonData.tag);
2829 
2830   j = 0;
2831   j = sprintf(buffer," corners=");
2832   for (i=0; i<element_descriptors[theSonData.tag]->corners_of_elem; i++)
2833   {
2834     j += sprintf(buffer+j,"%2d ",(int)theSonData.corners[i]);
2835   }
2836   Printf(buffer);
2837 
2838   j = 0;
2839   j += sprintf(buffer,"  nb=");
2840   for (i=0; i<element_descriptors[theSonData.tag]->sides_of_elem; i++)
2841   {
2842     j += sprintf(buffer+j,"%2d ",(int)theSonData.nb[i]);
2843   }
2844   Printf(buffer);
2845 
2846   Printf("  path of depth %d=",pd);
2847   /*for (i=8*sizeof(INT)-1; i>=0; i--)
2848      {
2849           sprintf(buffer,"%d",(int)((theSonData.path>>i) & 0x1));
2850           if (i%2 == 0 && theSonData.tag == TETRAHEDRON)	sprintf(buffer+1," ");
2851           if (i%3 == 0 && theSonData.tag == HEXAHEDRON)	sprintf(buffer+1," ");
2852           Printf(buffer);
2853      }*/
2854   if (pd>=MAX_PATH_DEPTH)
2855     Printf(" ERROR: path depth > MAX_PATH_DEPTH");
2856   else
2857     for (j=0; j<pd; j++)
2858     {
2859       int ns = NEXTSIDE(path,j);
2860       Printf("%2d",ns);
2861     }
2862 
2863   return(0);
2864 }
2865 
2866 /****************************************************************************/
2867 /** \brief
2868    ShowRefRule -
2869 
2870    SYNOPSIS:
2871    INT ShowRefRule (INT tag, INT nb);
2872 
2873    PARAMETERS:
2874    \param tag
2875    \param nb
2876 
2877    DESCRIPTION:
2878 
2879 
2880    \return
2881    INT
2882  */
2883 /****************************************************************************/
2884 
ShowRefRuleX(INT tag,INT nb,PrintfProcPtr Printf)2885 INT NS_DIM_PREFIX ShowRefRuleX (INT tag, INT nb, PrintfProcPtr Printf)
2886 {
2887   INT i;
2888   REFRULE *theRule;
2889 
2890   if (MaxRules[tag]<=nb)
2891   {
2892     Printf("ShowRefRule(): ERROR: nb=%d but MaxRules[%d]=%d\n",nb,tag,MaxRules[tag]);
2893     return (1);
2894   }
2895 
2896   theRule=&(RefRules[tag][nb]);
2897 
2898   /* header */
2899   Printf("\n");
2900   Printf("RefRule %3d:\n",nb);
2901 
2902   /* nsons, mark and class */
2903   Printf("   tag=%d mark=%3d class=%2d, nsons=%d\n",(int)theRule->tag,(int)theRule->mark,(int)theRule->rclass,(int)theRule->nsons);
2904 
2905   /* pattern */
2906   Printf("   pattern= ");
2907   for (i=0; i<(element_descriptors[tag]->edges_of_elem+element_descriptors[tag]->sides_of_elem+1); i++)
2908     Printf("%2d ",(int)theRule->pattern[i]);
2909   Printf("\n");
2910 
2911   /* pat */
2912   Printf("   pat    = ");
2913   for (i=0; i<(element_descriptors[tag]->edges_of_elem+element_descriptors[tag]->sides_of_elem+1); i++)
2914     Printf("%2d ",(int)((theRule->pat>>i) & 0x1));
2915   Printf("\n");
2916 
2917   /* sonandnode */
2918   for (i=0; i<MAX_NEW_CORNERS(tag); i++)
2919   {
2920     Printf("   newnode %2d: sonandnode[%2d][0]=%2d",i,i,(int)theRule->sonandnode[i][0]);
2921     Printf("  [%2d][1]=%2d\n",i,(int)theRule->sonandnode[i][1]);
2922   }
2923   Printf("\n");
2924 
2925   /* print edge data
2926      Printf("   Edge data\n");
2927      for (i=0; i<MAX_NEW_EDGES(tag); i++)
2928      {
2929           Printf("      e %2d: ",i);
2930           PrintEdgeData(theRule->edges[i]);
2931           if (i%2 == 1) Printf("\n");
2932      }
2933      Printf("\n");*/
2934 
2935   /* print sondata data */
2936   Printf("   Son data\n");
2937   for (i=0; i<(int)theRule->nsons; i++)
2938   {
2939     Printf("      son %2d: ",i);
2940     PrintSonData(theRule->sons[i],Printf);
2941     Printf("\n");
2942   }
2943 
2944   return (0);
2945 }
2946 
ShowRefRule(INT tag,INT nb)2947 INT NS_DIM_PREFIX ShowRefRule (INT tag, INT nb)
2948 {
2949   return (ShowRefRuleX(tag,nb,UserWriteF));
2950 }
2951 
2952 
2953 
2954 #ifdef __THREEDIM__
2955 
2956 /****************************************************************************/
2957 /** \brief
2958    InitRuleManager3D - Read the rule data set and initialize the rules
2959 
2960    This function reads the rule data set and initializes the rules data structure for tetrahedrons. Initializes the regular refinement rules (red rules) for hexahedrons. Irregular refinement of green closure is done algorithmically.
2961 
2962    \return
2963    .n   0 if ok
2964    .n   >0 if an error occurs
2965  */
2966 /****************************************************************************/
2967 
2968 #ifdef DUNE_UGGRID_TET_RULESET
2969 #  include "RefRules.cc"
2970 #endif
2971 
InitRuleManager3D(void)2972 static INT InitRuleManager3D (void)
2973 {
2974   FULLREFRULE *newFRR;
2975   int nRules;
2976 
2977   /* now make rules for tetrahedrons globally available */
2978   MaxNewCorners[TETRAHEDRON] = 11;
2979   MaxNewEdges[TETRAHEDRON] = 16;
2980   CenterNodeIndex[TETRAHEDRON] = 10;
2981 
2982 #ifdef DUNE_UGGRID_TET_RULESET
2983   RefRules[TETRAHEDRON] = tetrahedronRefinementRules;
2984   MaxRules[TETRAHEDRON] = nTetrahedronRefinementRules;
2985   Pattern2Rule[TETRAHEDRON] = pattern2RuleTetrahedron;
2986 #else
2987   RefRules[TETRAHEDRON] = TetrahedronRules;
2988   MaxRules[TETRAHEDRON] = MAX_TET_RULES;
2989 #endif
2990 
2991 
2992   /************************************************************************/
2993   /*																		*/
2994   /*  init refinement rules from for pyramids                           */
2995   /*																		*/
2996   /************************************************************************/
2997 
2998   nRules = MAX_PYR_RULES;
2999 
3000   /* make rules for pyramids globally available */
3001   MaxRules[PYRAMID] = nRules;
3002   MaxNewCorners[PYRAMID] = 19;
3003   MaxNewEdges[PYRAMID] = 54;
3004   CenterNodeIndex[PYRAMID] = 18;
3005   RefRules[PYRAMID] = PyramidRules;
3006 
3007   /************************************************************************/
3008   /*                                                                      */
3009   /*  init refinement rules for prisms                                    */
3010   /*                                                                      */
3011   /************************************************************************/
3012 
3013   nRules = MAX_PRI_RULES;
3014 
3015   /* make rules for prisms globally available */
3016   MaxRules[PRISM] = nRules;
3017   MaxNewCorners[PRISM] = 19;
3018   MaxNewEdges[PRISM] = 54;
3019   CenterNodeIndex[PRISM] = 18;
3020   RefRules[PRISM] = PrismRules;
3021 
3022   /************************************************************************/
3023   /*																		*/
3024   /*  init refinement rules from for hexahedrons                        */
3025   /*																		*/
3026   /************************************************************************/
3027 
3028   nRules = MAX_HEX_RULES;
3029 
3030   /* make rules for tetrahedrons globally available */
3031   MaxRules[HEXAHEDRON] = nRules;
3032   MaxNewCorners[HEXAHEDRON] = 19;
3033   MaxNewEdges[HEXAHEDRON] = 54;
3034   CenterNodeIndex[HEXAHEDRON] = 18;
3035   RefRules[HEXAHEDRON] = HexahedronRules;
3036 
3037 
3038   /************************************************************************/
3039   /*																		*/
3040   /* install best full refrules for tetrahedrons							*/
3041   /*																		*/
3042   /************************************************************************/
3043 
3044   /* install the /Menu directory */
3045   if (ChangeEnvDir("/")==NULL)
3046   {
3047     PrintErrorMessage('F',"InitRuleManager3D","could not changedir to root");
3048     return(__LINE__);
3049   }
3050   theBFRRDirID = GetNewEnvDirID();
3051   if (MakeEnvItem("best full refrule",theBFRRDirID,sizeof(ENVDIR))==NULL)
3052   {
3053     PrintErrorMessage('F',"InitRuleManager3D","could not install '/best full refrule' dir");
3054     return(__LINE__);
3055   }
3056   if (ChangeEnvDir("/best full refrule")==NULL)
3057     return(__LINE__);
3058 
3059   theBFRRVarID = GetNewEnvVarID();
3060 
3061   newFRR = (FULLREFRULE *) MakeEnvItem("shortestie",theBFRRVarID,sizeof(FULLREFRULE));
3062   if (newFRR==NULL)
3063     return(__LINE__);
3064   newFRR->theFullRefRule = ShortestInteriorEdge;
3065 
3066   newFRR = (FULLREFRULE *) MakeEnvItem("maxper",theBFRRVarID,sizeof(FULLREFRULE));
3067   if (newFRR==NULL)
3068     return(__LINE__);
3069   newFRR->theFullRefRule = MaxPerpendicular;
3070 
3071   newFRR = (FULLREFRULE *) MakeEnvItem("mra",theBFRRVarID,sizeof(FULLREFRULE));
3072   if (newFRR==NULL)
3073     return(__LINE__);
3074   newFRR->theFullRefRule = MaxRightAngle;
3075 
3076   newFRR = (FULLREFRULE *) MakeEnvItem("maxarea",theBFRRVarID,sizeof(FULLREFRULE));
3077   if (newFRR==NULL)
3078     return(__LINE__);
3079   newFRR->theFullRefRule = MaxArea;
3080 
3081 #ifdef __ALLRULES__
3082   newFRR = (FULLREFRULE *) MakeEnvItem("minangle",theBFRRVarID,sizeof(FULLREFRULE));
3083   if (newFRR==NULL)
3084     return(__LINE__);
3085   newFRR->theFullRefRule = MinimalSideAngle;
3086 
3087   newFRR = (FULLREFRULE *) MakeEnvItem("bestm",theBFRRVarID,sizeof(FULLREFRULE));
3088   if (newFRR==NULL)
3089     return(__LINE__);
3090   newFRR->theFullRefRule = BestLaplaceMMatrix;
3091 
3092   newFRR = (FULLREFRULE *) MakeEnvItem("minentry",theBFRRVarID,sizeof(FULLREFRULE));
3093   if (newFRR==NULL)
3094     return(__LINE__);
3095   newFRR->theFullRefRule = MinimalSideEntry;
3096 #endif
3097 
3098   /* default full refrule */
3099   theFullRefRule = ShortestInteriorEdge;
3100 
3101   UserWrite("3D RefRules installed\n");
3102 
3103   return (GM_OK);
3104 }
3105 
3106 
3107 #endif /* __THREEDIM__ */
3108 
3109 #ifdef __TWODIM__
3110 
3111 
3112 /****************************************************************************/
3113 /** \brief
3114    InitRuleManager2D - Initializes rules for triangles and quadrilaterals
3115 
3116    SYNOPSIS:
3117    static INT InitRuleManager2D (void);
3118 
3119    PARAMETERS:
3120    .  void
3121 
3122    DESCRIPTION:
3123    This function initializes rules for triangles and quadrilaterals
3124 
3125    \return
3126    INT
3127    .n   0 - ok
3128    .n   >0 - error
3129  */
3130 /****************************************************************************/
3131 
InitRuleManager2D(void)3132 static INT InitRuleManager2D (void)
3133 {
3134   /************************************************************************/
3135   /*																		*/
3136   /*  init refinement rules for triangles                                       */
3137   /*																		*/
3138   /************************************************************************/
3139 
3140   /* there are 8 = 2^3 different patterns */
3141   /* but why is there a 17 here? probably could be 8... */
3142   static const SHORT pattern2RuleTriangle[17] = {
3143     /* 0: */ T_COPY,                           /* 0 0 0 */
3144     /* 1: */ T_BISECT_1_0,             /* 0 0 1 */
3145     /* 2: */ T_BISECT_1_1,             /* 0 1 0 */
3146     /* 3: */ T_BISECT_2_T1_0,          /* 0 1 1 */
3147     /* 4: */ T_BISECT_1_2,                     /* 1 0 0 */
3148     /* 5: */ NOINDEX,                  /* 1 0 1 */
3149     /* 6: */ NOINDEX,                  /* 1 1 0 */
3150     /* 7: */ T_RED,                            /* 1 1 1 */
3151   };
3152   Pattern2Rule[TRIANGLE] = pattern2RuleTriangle;
3153 
3154   /* Pattern2Rule gives the starting index for rules with same pattern */
3155 
3156   /* now make rules for triangles globally available */
3157   MaxRules[TRIANGLE] = MAX_TRI_RULES;
3158   MaxNewCorners[TRIANGLE] = 3;
3159   MaxNewEdges[TRIANGLE] = 9;
3160   CenterNodeIndex[TRIANGLE] = 4;
3161   RefRules[TRIANGLE] = TriangleRules;
3162 
3163 
3164   /************************************************************************/
3165   /*																		*/
3166   /*  init refinement rules for quadrilaterals                          */
3167   /*																		*/
3168   /************************************************************************/
3169 
3170   /* there are 32 = 2^5 different patterns */
3171   static const SHORT pattern2RuleQuadrilateral[32] = {
3172     /* Pattern2Rule gives the starting index for rules with same pattern */
3173     /*  0: */ NOINDEX,                    /* 0 0 0 0 0 */
3174     /*  1: */ NOINDEX,                    /* 0 0 0 0 1 */
3175     /*  2: */ NOINDEX,                    /* 0 0 0 1 0 */
3176     /*  3: */ NOINDEX,                    /* 0 0 0 1 1 */
3177     /*  4: */ NOINDEX,                    /* 0 0 1 0 0 */
3178     /*  5: */ NOINDEX,                    /* 0 0 1 0 1 */
3179     /*  6: */ NOINDEX,                    /* 0 0 1 1 0 */
3180     /*  7: */ NOINDEX,                    /* 0 0 1 1 1 */
3181     /*  8: */ NOINDEX,                    /* 0 1 0 0 0 */
3182     /*  9: */ NOINDEX,                    /* 0 1 0 0 1 */
3183     /* 10: */ NOINDEX,                    /* 0 1 0 1 0 */
3184     /* 11: */ NOINDEX,                    /* 0 1 0 1 1 */
3185     /* 12: */ NOINDEX,                    /* 0 1 1 0 0 */
3186     /* 13: */ NOINDEX,                    /* 0 1 1 0 1 */
3187     /* 14: */ NOINDEX,                    /* 0 1 1 1 0 */
3188     /* 15: */ NOINDEX,                    /* 0 1 1 1 1 */
3189     /* 16: */ NOINDEX,                    /* 1 0 0 0 0 */
3190     /* 17: */ NOINDEX,                    /* 1 0 0 0 1 */
3191     /* 18: */ NOINDEX,                    /* 1 0 0 1 0 */
3192     /* 19: */ NOINDEX,                    /* 1 0 0 1 1 */
3193     /* 20: */ NOINDEX,                    /* 1 0 1 0 0 */
3194     /* 21: */ NOINDEX,                    /* 1 0 1 0 1 */
3195     /* 22: */ NOINDEX,                    /* 1 0 1 1 0 */
3196     /* 23: */ NOINDEX,                    /* 1 0 1 1 1 */
3197     /* 24: */ NOINDEX,                    /* 1 1 0 0 0 */
3198     /* 25: */ NOINDEX,                    /* 1 1 0 0 1 */
3199     /* 26: */ NOINDEX,                    /* 1 1 0 1 0 */
3200     /* 27: */ NOINDEX,                    /* 1 1 0 1 1 */
3201     /* 28: */ NOINDEX,                    /* 1 1 1 0 0 */
3202     /* 29: */ NOINDEX,                    /* 1 1 1 0 1 */
3203     /* 30: */ NOINDEX,                    /* 1 1 1 1 0 */
3204     /* 31: */ Q_RED,                      /* 1 1 1 1 1 */
3205   };
3206   Pattern2Rule[QUADRILATERAL] = pattern2RuleQuadrilateral;
3207 
3208 
3209   /* now make rules for quadrilaterals globally available */
3210   MaxRules[QUADRILATERAL] = MAX_QUA_RULES;
3211   MaxNewCorners[QUADRILATERAL] = 4;
3212   MaxNewEdges[QUADRILATERAL] = 12;
3213   CenterNodeIndex[QUADRILATERAL] = 4;
3214   RefRules[QUADRILATERAL] = QuadrilateralRules;
3215 
3216   return (GM_OK);
3217 }
3218 #endif /* __TWODIM__ */
3219 
3220 
3221 /****************************************************************************/
3222 /** \brief InitRuleManager Initialize the 2- or 3D rule set
3223 
3224    This function initialize the 2- or 3D rule set
3225  */
3226 /****************************************************************************/
3227 
InitRuleManager(void)3228 INT NS_DIM_PREFIX InitRuleManager (void)
3229 {
3230   INT err;
3231 
3232   /* init 2- or 3D rulemanager */
3233   if ((err=CONCAT(InitRuleManager,DIM,D) ()) != GM_OK)
3234   {
3235     SetHiWrd(err,__LINE__);
3236     return(err);
3237   }
3238   return (0);
3239 }
3240