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