1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 /** \file
4  * \brief Encapsulates some UG macros and functions
5  */
6 
7 /** \todo Here only to provide the constant DBL_EPSILON.  There's maybe a better way? */
8 #include "float.h"
9 
10 namespace Dune {
11 
12   /** \brief Encapsulates a few UG methods and macros
13    *
14    * This class provides a wrapper to several methods and macros from
15    * UG.  There are two reasons for doing this.  First, we don't want
16    * to call UG macros directly from DUNE, because they pollute the
17    * namespace and therefore we undefine them all.  Secondly,  UG methods
18    * appear in the namespaces UG::D2 and UG::D3, but we need the dimension
19    * as a template parameter.
20    */
21 #if UG_DIM == 2
22   template<int dim>
23   class UG_NS {};
24 #endif
25 
26   template<>
27   class UG_NS< UG_DIM > {
28   public:
29 
30     // //////////////////////////////////////////////
31     //   Types exported by UG
32     // //////////////////////////////////////////////
33 
34 #if UG_DIM == 2
35 #define UG_NAMESPACE UG::D2
36 #else
37 #define UG_NAMESPACE UG::D3
38 #endif
39 
40     enum Priorities {
41       PrioNone = UG_NAMESPACE::PrioNone,
42       PrioMaster = UG_NAMESPACE::PrioMaster,
43       PrioBorder = UG_NAMESPACE::PrioBorder,
44 
45       PrioHGhost = UG_NAMESPACE::PrioHGhost,
46       PrioVGhost = UG_NAMESPACE::PrioVGhost,
47       PrioVHGhost = UG_NAMESPACE::PrioVHGhost
48     };
49 
50 
51     typedef UG_NAMESPACE ::RefinementRule RefinementRule;
52 
53     typedef UG_NAMESPACE ::CoeffProcPtr CoeffProcPtr;
54 
55     typedef UG_NAMESPACE ::UserProcPtr UserProcPtr;
56 
57     typedef UG_NAMESPACE ::BndSegFuncPtr BndSegFuncPtr;
58 
59     /** \brief This is actually a type of the UG algebra, not the grid.
60      * We need it to implement face indices and ids in 3d, since UG
61      * doesn't actually have objects for faces in 3d grids. */
62     typedef UG_NAMESPACE ::vector Vector;
63 
64     /** \brief UG type for a hierarchical grid */
65     typedef UG_NAMESPACE ::multigrid MultiGrid;
66 
67     /** \brief UG type for a level grid */
68     typedef UG_NAMESPACE ::grid Grid;
69 
70     typedef UG_NAMESPACE ::edge Edge;
71 
72     typedef UG_NAMESPACE ::node Node;
73 
74     typedef UG_NAMESPACE ::element Element;
75 
76     typedef UG_NAMESPACE ::vertex Vertex;
77 
78     typedef UG_NAMESPACE ::BVP BVP;
79 
80     typedef UG_NAMESPACE ::BVP_DESC BVP_DESC;
81 
82     /** \brief Point on a UG boundary patch */
83     typedef UG_NAMESPACE ::BNDP BNDP;
84 
85     /** \brief Types of the subentities parametrized by the codimension.  Gets specialized below */
86     template <int codim>
87     class Entity;
88 
89     // Type used for local and global ids
90 #ifdef ModelP
91     typedef UG_NAMESPACE::DDD_GID UG_ID_TYPE;
92 #else
93     typedef UG::INT UG_ID_TYPE;
94 #endif
95 
96 #ifdef ModelP
97     /* DDD Interfaces */
98     typedef UG_NAMESPACE::DDD_IF_DIR DDD_IF_DIR;
99     typedef UG_NAMESPACE::DDD_IF DDD_IF;
100     typedef UG_NAMESPACE::DDD_OBJ DDD_OBJ;
101     typedef UG_NAMESPACE::DDD_HEADER DDD_HEADER;
102 
DDD_IFOneway(DDD::DDDContext & context,DDD_IF dddIf,DDD_IF_DIR dddIfDir,size_t s,UG_NAMESPACE::ComProcPtr2 gather,UG_NAMESPACE::ComProcPtr2 scatter)103     static void DDD_IFOneway(
104 #if DUNE_UGGRID_HAVE_DDDCONTEXT
105                              DDD::DDDContext& context,
106 #endif
107                              DDD_IF dddIf,
108                              DDD_IF_DIR dddIfDir,
109                              size_t s,
110 #if DUNE_UGGRID_HAVE_DDDCONTEXT
111                              UG_NAMESPACE::ComProcPtr2 gather,
112                              UG_NAMESPACE::ComProcPtr2 scatter
113 #else
114                              UG_NAMESPACE::ComProcPtr gather,
115                              UG_NAMESPACE::ComProcPtr scatter
116 #endif
117       )
118     {
119       UG_NAMESPACE::DDD_IFOneway(
120 #if DUNE_UGGRID_HAVE_DDDCONTEXT
121         context,
122 #endif
123         dddIf, dddIfDir, s, gather, scatter);
124     }
125 
DDD_InfoProcList(DDD::DDDContext & context,DDD_HEADER * hdr)126     static int *DDD_InfoProcList(
127 #if DUNE_UGGRID_HAVE_DDDCONTEXT
128                              DDD::DDDContext& context,
129 #endif
130       DDD_HEADER *hdr)
131     {
132 #if DUNE_UGGRID_HAVE_DDDCONTEXT
133       //return DDD::DDD_InfoProcList(context, hdr);
134       return UG_NAMESPACE::DDD_InfoProcList(context, hdr);
135 #else
136       return UG_NAMESPACE::DDD_InfoProcList(hdr);
137 #endif
138     }
139 
IF_FORWARD()140     static DDD_IF_DIR IF_FORWARD()
141     {
142       return UG_NAMESPACE::IF_FORWARD;
143     }
144 
IF_BACKWARD()145     static DDD_IF_DIR IF_BACKWARD()
146     {
147       return UG_NAMESPACE::IF_BACKWARD;
148     }
149 
150 #if DUNE_UGGRID_HAVE_DDDCONTEXT
151 #  define DDD_CONTEXT_PARAM const DDD::DDDContext& context
152 #  define DDD_GET_IF(id) (UG_NAMESPACE::ddd_ctrl(context).id)
153 #else
154 #  define DDD_CONTEXT_PARAM
155 #  define DDD_GET_IF(id) (UG_NAMESPACE::id)
156 #endif
157 
158     /*! Master->HGhost/VHGhost */
ElementIF(DDD_CONTEXT_PARAM)159     static DDD_IF ElementIF(DDD_CONTEXT_PARAM)
160     {
161       return DDD_GET_IF(ElementIF);
162     }
163 
164     /*! ElementSymmIF: Master/HGhost/VHGhost */
ElementSymmIF(DDD_CONTEXT_PARAM)165     static DDD_IF ElementSymmIF(DDD_CONTEXT_PARAM)
166     {
167       return DDD_GET_IF(ElementSymmIF);
168     }
169 
170     /*! ElementVIF: Master->VGhost/VHGhost */
ElementVIF(DDD_CONTEXT_PARAM)171     static DDD_IF ElementVIF(DDD_CONTEXT_PARAM)
172     {
173       return DDD_GET_IF(ElementVIF);
174     }
175 
176     /*! ElementSymmVIF: Master/VGhost/VHGhost" */
ElementSymmVIF(DDD_CONTEXT_PARAM)177     static DDD_IF ElementSymmVIF(DDD_CONTEXT_PARAM)
178     {
179       return DDD_GET_IF(ElementSymmVIF);
180     }
181 
182     /*! Master->VGhost/HGhost/VHGhost */
ElementVHIF(DDD_CONTEXT_PARAM)183     static DDD_IF ElementVHIF(DDD_CONTEXT_PARAM)
184     {
185       return DDD_GET_IF(ElementVHIF);
186     }
187 
188     /*! ElementSymmVHIF: Master/VGhost/HGhost/VHGhost */
ElementSymmVHIF(DDD_CONTEXT_PARAM)189     static DDD_IF ElementSymmVHIF(DDD_CONTEXT_PARAM)
190     {
191       return DDD_GET_IF(ElementSymmVHIF);
192     }
193 
194     /*! BorderNodeIF: Border->Master */
BorderNodeIF(DDD_CONTEXT_PARAM)195     static DDD_IF BorderNodeIF(DDD_CONTEXT_PARAM)
196     {
197       return DDD_GET_IF(BorderNodeIF);
198     }
199 
200     /*! BorderNodeSymmIF: Border/Master */
BorderNodeSymmIF(DDD_CONTEXT_PARAM)201     static DDD_IF BorderNodeSymmIF(DDD_CONTEXT_PARAM)
202     {
203       return DDD_GET_IF(BorderNodeSymmIF);
204     }
205 
206     /*! OuterNodeIF: Master->HGhost/VGhost */
OuterNodeIF(DDD_CONTEXT_PARAM)207     static DDD_IF OuterNodeIF(DDD_CONTEXT_PARAM)
208     {
209       return DDD_GET_IF(OuterNodeIF);
210     }
211 
212 
213     /*! NodeVIF: Master->VGhost/VHGhost */
NodeVIF(DDD_CONTEXT_PARAM)214     static DDD_IF NodeVIF(DDD_CONTEXT_PARAM)
215     {
216       return DDD_GET_IF(NodeVIF);
217     }
218 
219     /*! NodeIF: Master->VGhost/HGhost/VHGhost */
NodeIF(DDD_CONTEXT_PARAM)220     static DDD_IF NodeIF(DDD_CONTEXT_PARAM)
221     {
222       return DDD_GET_IF(NodeIF);
223     }
224 
225     /*! NodeAllIF: All/All */
NodeAllIF(DDD_CONTEXT_PARAM)226     static DDD_IF NodeAllIF(DDD_CONTEXT_PARAM)
227     {
228       return DDD_GET_IF(NodeAllIF);
229     }
230 
231     /*! Node_InteriorBorder_All_IF: Master/Border->All */
NodeInteriorBorderAllIF(DDD_CONTEXT_PARAM)232     static DDD_IF NodeInteriorBorderAllIF(DDD_CONTEXT_PARAM)
233     {
234       return DDD_GET_IF(Node_InteriorBorder_All_IF);
235     }
236 
237     /*! BorderVectorIF: Border->Master */
BorderVectorIF(DDD_CONTEXT_PARAM)238     static DDD_IF BorderVectorIF(DDD_CONTEXT_PARAM)
239     {
240       return DDD_GET_IF(BorderVectorIF);
241     }
242 
243     /*! BorderVectorSymmIF: Master/Border */
BorderVectorSymmIF(DDD_CONTEXT_PARAM)244     static DDD_IF BorderVectorSymmIF(DDD_CONTEXT_PARAM)
245     {
246       return DDD_GET_IF(BorderVectorSymmIF);
247     }
248 
249     /*! OuterVectorIF: Master->HGhost/VHGhost */
OuterVectorIF(DDD_CONTEXT_PARAM)250     static DDD_IF OuterVectorIF(DDD_CONTEXT_PARAM)
251     {
252       return DDD_GET_IF(OuterVectorIF);
253     }
254 
255     /*! OuterVectorSymmIF: Master/Border/HGhost/VHGhost */
OuterVectorSymmIF(DDD_CONTEXT_PARAM)256     static DDD_IF OuterVectorSymmIF(DDD_CONTEXT_PARAM)
257     {
258       return DDD_GET_IF(OuterVectorSymmIF);
259     }
260 
261     /*! VectorVIF: Master->VGhost/VHGhost */
VectorVIF(DDD_CONTEXT_PARAM)262     static DDD_IF VectorVIF(DDD_CONTEXT_PARAM)
263     {
264       return DDD_GET_IF(VectorVIF);
265     }
266 
267     /*! VectorVAllIF: Master/Border/VGhost/VHGhost->Master/Border */
VectorVAllIF(DDD_CONTEXT_PARAM)268     static DDD_IF VectorVAllIF(DDD_CONTEXT_PARAM)
269     {
270       return DDD_GET_IF(VectorVAllIF);
271     }
272 
273     /*! VectorIF: Master->VGhost/VHGhost/HGhost */
VectorIF(DDD_CONTEXT_PARAM)274     static DDD_IF VectorIF(DDD_CONTEXT_PARAM)
275     {
276       return DDD_GET_IF(VectorIF);
277     }
278 
FacetInteriorBorderAllIF(DDD_CONTEXT_PARAM)279     static DDD_IF FacetInteriorBorderAllIF(DDD_CONTEXT_PARAM)
280     {
281       return DDD_GET_IF(Facet_InteriorBorder_All_IF);
282     }
283 
FacetAllAllIF(DDD_CONTEXT_PARAM)284     static DDD_IF FacetAllAllIF(DDD_CONTEXT_PARAM)
285     {
286       return DDD_GET_IF(Facet_All_All_IF);
287     }
288 
289     /*! Master->HGhost/VHGhost */
EdgeIF(DDD_CONTEXT_PARAM)290     static DDD_IF EdgeIF(DDD_CONTEXT_PARAM)
291     {
292       return DDD_GET_IF(EdgeIF);
293     }
294 
295     /*! EdgeSymmIF: Master/HGhost/VHGhost */
BorderEdgeSymmIF(DDD_CONTEXT_PARAM)296     static DDD_IF BorderEdgeSymmIF(DDD_CONTEXT_PARAM)
297     {
298       return DDD_GET_IF(BorderEdgeSymmIF);
299     }
300 
301     /*! EdgeHIF: Master/HGhost/VHGhost */
EdgeHIF(DDD_CONTEXT_PARAM)302     static DDD_IF EdgeHIF(DDD_CONTEXT_PARAM)
303     {
304       return DDD_GET_IF(EdgeHIF);
305     }
306 
307     /*! EdgeVHIF: Master->VGhost/HGhost/VHGhost */
EdgeVHIF(DDD_CONTEXT_PARAM)308     static DDD_IF EdgeVHIF(DDD_CONTEXT_PARAM)
309     {
310       return DDD_GET_IF(EdgeVHIF);
311     }
312 
313     /*! EdgeSymmVHIF: Master/VGhost/HGhost/VHGhost */
EdgeSymmVHIF(DDD_CONTEXT_PARAM)314     static DDD_IF EdgeSymmVHIF(DDD_CONTEXT_PARAM)
315     {
316       return DDD_GET_IF(EdgeSymmVHIF);
317     }
318 
319 #undef DDD_CONTEXT_PARAM
320 #undef DDD_GET_IF
321 
322     /** \brief Encapsulates the UG EPRIO macro */
EPriority(const UG_NS<UG_DIM>::Element * element)323     static int EPriority(const UG_NS< UG_DIM >::Element* element)
324     {
325       return EPRIO(element);
326     }
327 
328     /** \brief Returns the priority of the side vector */
Priority(const UG_NS<UG_DIM>::Vector * side)329     static int Priority(const UG_NS< UG_DIM >::Vector* side)
330     {
331       return PARHDR(side)->prio;
332     }
333 
334     /** \brief Returns the priority of the edge (the UG EPRIO macro) */
Priority(const UG_NS<UG_DIM>::Edge * edge)335     static int Priority(const UG_NS< UG_DIM >::Edge* edge)
336     {
337       return PARHDR(edge)->prio;
338     }
339 
340     /** \brief Returns the priority of the node (the UG EPRIO macro) */
Priority(const UG_NS<UG_DIM>::Node * node)341     static int Priority(const UG_NS< UG_DIM >::Node* node)
342     {
343       return PARHDR(node)->prio;
344     }
345 
ParHdr(UG_NS<UG_DIM>::Vector * side)346     static DDD_HEADER* ParHdr(UG_NS< UG_DIM >::Vector *side)
347     {
348       return PARHDR(side);
349     }
350 
ParHdr(UG_NS<UG_DIM>::Edge * edge)351     static DDD_HEADER* ParHdr(UG_NS< UG_DIM >::Edge *edge)
352     {
353       return PARHDR(edge);
354     }
355 
ParHdr(UG_NS<UG_DIM>::Node * node)356     static DDD_HEADER* ParHdr(UG_NS< UG_DIM >::Node *node)
357     {
358       return PARHDR(node);
359     }
360 
361     /** \brief This entry tells the UG load balancer what rank this particular element
362      * is supposed to be sent to.
363      */
Partition(UG_NS<UG_DIM>::Element * element)364     static UG::INT& Partition(UG_NS< UG_DIM >::Element* element)
365     {
366       return PARTITION(element);
367     }
368 #endif
369 
370     // //////////////////////////////////////////////
371     //   Constants exported by UG
372     // //////////////////////////////////////////////
373 
374     enum {GM_REFINE_NOT_CLOSED = UG_NAMESPACE ::GM_REFINE_NOT_CLOSED};
375 
376     enum {GM_COPY_ALL = UG_NAMESPACE ::GM_COPY_ALL};
377 
378     enum {GM_REFINE_TRULY_LOCAL = UG_NAMESPACE ::GM_REFINE_TRULY_LOCAL};
379 
380     enum {GM_REFINE_PARALLEL = UG_NAMESPACE ::GM_REFINE_PARALLEL};
381 
382     enum {GM_REFINE_NOHEAPTEST = UG_NAMESPACE ::GM_REFINE_NOHEAPTEST};
383 
384     /** \brief Control word entries */
385     enum {NEWEL_CE      = UG_NAMESPACE ::NEWEL_CE,
386           COARSEN_CE    = UG_NAMESPACE ::COARSEN_CE,
387           ECLASS_CE     = UG_NAMESPACE ::ECLASS_CE,
388           MARK_CE       = UG_NAMESPACE ::MARK_CE,
389           REFINE_CE     = UG_NAMESPACE ::REFINE_CE};
390 
391     /** \brief Refinement rules */
392     enum {NO_REFINEMENT = UG_NAMESPACE ::NO_REFINEMENT,
393           RED           = UG_NAMESPACE ::RED,
394           COARSE        = UG_NAMESPACE ::COARSE};
395 
396     enum {RED_CLASS = UG_NAMESPACE ::RED_CLASS};
397 
398     enum {GM_OK = UG_NAMESPACE ::GM_OK};
399 
400     enum {MAX_SONS = UG_NAMESPACE ::MAX_SONS};
401 
402     /** \brief The PFIRSTNODE macro which returns the first node in a
403      * grid even in a parallel setting.
404      */
PFirstNode(const UG_NS<UG_DIM>::Grid * grid)405     static UG_NS< UG_DIM >::Node* PFirstNode(const UG_NS< UG_DIM >::Grid* grid) {
406       using UG_NAMESPACE ::PrioHGhost;
407       using UG_NAMESPACE ::PrioVGhost;
408       using UG_NAMESPACE ::PrioVHGhost;
409       using UG_NAMESPACE ::PrioMaster;
410       using UG_NAMESPACE ::PrioBorder;
411       using UG_NAMESPACE ::ELEMENT_LIST;
412       using UG_NAMESPACE ::NODE_LIST;
413       return PFIRSTNODE(grid);
414     }
415 
416     /** \brief The FIRSTNODE macro which returns the first node in a
417      * grid even in a parallel setting.
418      */
FirstNode(UG_NS<UG_DIM>::Grid * grid)419     static UG_NS< UG_DIM >::Node* FirstNode(UG_NS< UG_DIM >::Grid* grid) {
420       using UG_NAMESPACE ::PrioHGhost;
421       using UG_NAMESPACE ::PrioVGhost;
422       using UG_NAMESPACE ::PrioVHGhost;
423       using UG_NAMESPACE ::PrioMaster;
424       using UG_NAMESPACE ::PrioBorder;
425       using UG_NAMESPACE ::ELEMENT_LIST;
426       using UG_NAMESPACE ::NODE_LIST;
427       return FIRSTNODE(grid);
428     }
429 
430     /** \brief The PFIRSTELEMENT macro which returns the first element in a
431      * grid even in a parallel setting.
432      */
PFirstElement(const UG_NS<UG_DIM>::Grid * grid)433     static UG_NS< UG_DIM >::Element* PFirstElement(const UG_NS< UG_DIM >::Grid* grid) {
434       using UG_NAMESPACE ::PrioHGhost;
435       using UG_NAMESPACE ::PrioVGhost;
436       using UG_NAMESPACE ::PrioVHGhost;
437       using UG_NAMESPACE ::PrioMaster;
438       using UG_NAMESPACE ::PrioBorder;
439       using UG_NAMESPACE ::ELEMENT_LIST;
440       using UG_NAMESPACE ::NODE_LIST;
441       return PFIRSTELEMENT(grid);
442     }
443 
444     /** \brief The FIRSTELEMENT macro which returns the first element in a
445      * grid even in a parallel setting.
446      */
FirstElement(UG_NS<UG_DIM>::Grid * grid)447     static UG_NS< UG_DIM >::Element* FirstElement(UG_NS< UG_DIM >::Grid* grid) {
448       using UG_NAMESPACE ::PrioHGhost;
449       using UG_NAMESPACE ::PrioVGhost;
450       using UG_NAMESPACE ::PrioVHGhost;
451       using UG_NAMESPACE ::PrioMaster;
452       using UG_NAMESPACE ::PrioBorder;
453       using UG_NAMESPACE ::ELEMENT_LIST;
454       return FIRSTELEMENT(grid);
455     }
456 
457     /** \brief Returns pointers to the coordinate arrays of a UG element */
Corner_Coordinates(const UG_NS<UG_DIM>::Element * theElement,double * x[])458     static int Corner_Coordinates(const UG_NS< UG_DIM >::Element* theElement, double* x[]) {
459       using UG_NAMESPACE ::NODE;
460       using UG_NAMESPACE ::TRIANGLE;
461       using UG_NAMESPACE ::QUADRILATERAL;
462       using UG_NAMESPACE ::TETRAHEDRON;
463       using UG_NAMESPACE ::PYRAMID;
464       using UG_NAMESPACE ::PRISM;
465       using UG_NAMESPACE ::n_offset;
466       using UG::UINT;
467       int n;
468       CORNER_COORDINATES(theElement, n, x);
469       return n;
470     }
471 
472     /** \brief Returns pointers to the coordinate arrays of a UG node */
Corner_Coordinates(const UG_NS<UG_DIM>::Node * theNode,double * x[])473     static int Corner_Coordinates(const UG_NS< UG_DIM >::Node* theNode, double* x[]) {
474       x[0] = theNode->myvertex->iv.x;
475       return 1;
476     }
477 
478     /** \brief Returns pointers to the coordinate arrays of a UG edge */
Corner_Coordinates(const UG_NS<UG_DIM>::Edge * theEdge,double * x[])479     static int Corner_Coordinates(const UG_NS< UG_DIM >::Edge* theEdge, double* x[]) {
480       x[0] = theEdge->links[0].nbnode->myvertex->iv.x;
481       x[1] = theEdge->links[1].nbnode->myvertex->iv.x;
482       return 2;
483     }
484 
485     /** \brief Returns pointers to the coordinate arrays of a UG vector */
Corner_Coordinates(const UG_NS<UG_DIM>::Vector * theVector,double * x[])486     static int Corner_Coordinates(const UG_NS< UG_DIM >::Vector* theVector, double* x[]) {
487       UG_NS< UG_DIM >::Element* center;
488       unsigned int side;
489       UG_NS< UG_DIM >::GetElementAndSideFromSideVector(theVector, center, side);
490       int n = Corners_Of_Side(center, side);
491       for (int i = 0; i < n; i++)
492       {
493         unsigned idxInElem = Corner_Of_Side(center, side, i);
494         x[i] = Corner(center, idxInElem)->myvertex->iv.x;
495       }
496       return n;
497     }
498 
GlobalToLocal(int n,const double ** cornerCoords,const double * EvalPoint,double * localCoord)499     static int GlobalToLocal(int n, const double** cornerCoords,
500                              const double* EvalPoint, double* localCoord) {
501       if (UG_DIM==2)
502         // in 2d we can call this only for triangles and quadrilaterals
503         assert(n==3 or n==4);
504       else
505         // in 3d: tetrahedra, pyramids, prisms, hexahedra
506         assert(n==4 or n==5 or n==6 or n==8);
507       return UG_NAMESPACE ::UG_GlobalToLocal(n, cornerCoords, EvalPoint, localCoord);
508     }
509 
510     /** \brief Computes the element volume */
Area_Of_Element(int n,const double ** cornerCoords)511     static double Area_Of_Element(int n, const double** cornerCoords) {
512       double area = 0.0;
513       using UG::DOUBLE;
514       using UG_NAMESPACE ::DOUBLE_VECTOR;
515 #if UG_DIM == 2
516       AREA_OF_ELEMENT_2D(n,cornerCoords,area);
517 #else
518       AREA_OF_ELEMENT_3D(n,cornerCoords,area);
519 #endif
520       return area;
521     }
522 
myLevel(const UG_NS<UG_DIM>::Element * theElement)523     static int myLevel (const UG_NS< UG_DIM >::Element* theElement) {
524       using UG::UINT;
525       return LEVEL(theElement);
526     }
527 
myLevel(const UG_NS<UG_DIM>::Node * theNode)528     static int myLevel (const UG_NS< UG_DIM >::Node* theNode) {
529       using UG::UINT;
530       return LEVEL(theNode);
531     }
532 
myLevel(const UG_NS<UG_DIM>::Edge * theEdge)533     static int myLevel (const UG_NS< UG_DIM >::Edge* theEdge) {
534       using UG::UINT;
535       return LEVEL(theEdge);
536     }
537 
myLevel(const UG_NS<UG_DIM>::Vector * theVector)538     static int myLevel (const UG_NS< UG_DIM >::Vector* theVector) {
539       return myLevel((UG_NS< UG_DIM >::Element*)VOBJECT(theVector));
540     }
541 
542     //! return true if element has an exact copy on the next level
hasCopy(const UG_NS<UG_DIM>::Element * theElement)543     static bool hasCopy (const UG_NS< UG_DIM >::Element* theElement) {
544       using UG_NAMESPACE ::ELEMENT;
545       using UG_NAMESPACE ::control_entries;
546       using UG::UINT;
547       using UG_NAMESPACE ::REFINECLASS_CE;
548       using UG_NAMESPACE ::YELLOW_CLASS;
549       return REFINECLASS(theElement) == YELLOW_CLASS;
550     }
551 
552     //! Returns true if element is on level 0 or has been created by red refinement
isRegular(const UG_NS<UG_DIM>::Element * theElement)553     static bool isRegular (const UG_NS< UG_DIM >::Element* theElement) {
554       using UG_NAMESPACE ::ELEMENT;
555       using UG_NAMESPACE ::control_entries;
556       using UG::UINT;
557       return ECLASS(theElement) == RED_CLASS;
558     }
559 
560     //! \todo Please doc me!
Sides_Of_Elem(const UG_NS<UG_DIM>::Element * theElement)561     static int Sides_Of_Elem(const UG_NS< UG_DIM >::Element* theElement) {
562       using UG_NAMESPACE ::element_descriptors;
563       using UG::UINT;
564       return SIDES_OF_ELEM(theElement);
565     }
566 
567     //! Encapsulates the NBELEM macro
NbElem(const UG_NS<UG_DIM>::Element * theElement,int nb)568     static UG_NS<UG_DIM>::Element* NbElem(const UG_NS< UG_DIM >::Element* theElement, int nb) {
569       using UG_NAMESPACE ::ELEMENT;
570       using UG_NAMESPACE ::nb_offset;
571       using UG::UINT;
572       return NBELEM(theElement, nb);
573     }
574 
boundarySegmentIndex(const UG_NS<UG_DIM>::Element * theElement,int nb)575     static size_t boundarySegmentIndex(const UG_NS< UG_DIM >::Element* theElement, int nb) {
576       using UG_NAMESPACE ::BNDS;
577       using UG::UINT;
578       using UG_NAMESPACE ::side_offset;
579 
580       BNDS* bnds = ELEM_BNDS(theElement,nb);
581       size_t id = UG_NAMESPACE ::GetBoundarySegmentId(bnds);
582       return id;
583     }
584 
585     //! Returns true if the i-th side of the element is on the domain boundary
Side_On_Bnd(const UG_NS<UG_DIM>::Element * theElement,int i)586     static bool Side_On_Bnd(const UG_NS< UG_DIM >::Element* theElement, int i) {
587       using UG_NAMESPACE ::BNDS;
588       using UG_NAMESPACE ::BEOBJ;
589       using UG_NAMESPACE ::side_offset;
590       using UG::UINT;
591       using UG_NAMESPACE ::GM_OBJECTS;
592       return OBJT(theElement)==BEOBJ && SIDE_ON_BND(theElement, i);
593     }
594 
595     //! Returns true if at least one face of the element is a boundary face
isBoundaryElement(const UG_NS<UG_DIM>::Element * theElement)596     static bool isBoundaryElement(const UG_NS< UG_DIM >::Element* theElement) {
597       using UG_NAMESPACE ::BEOBJ;
598       using UG_NAMESPACE ::GM_OBJECTS;
599       using UG::UINT;
600       return OBJT(theElement)==BEOBJ;
601     }
602 
603     //! \todo Please doc me!
Edges_Of_Elem(const UG_NS<UG_DIM>::Element * theElement)604     static int Edges_Of_Elem(const UG_NS< UG_DIM >::Element* theElement) {
605       using UG_NAMESPACE ::element_descriptors;
606       using UG::UINT;
607       return EDGES_OF_ELEM(theElement);
608     }
609 
610     //! \todo Please doc me!
Corners_Of_Elem(const UG_NS<UG_DIM>::Element * theElement)611     static int Corners_Of_Elem(const UG_NS< UG_DIM >::Element* theElement) {
612       using UG_NAMESPACE ::element_descriptors;
613       using UG::UINT;
614       return CORNERS_OF_ELEM(theElement);
615     }
616 
617     /** \Brief the 'number of corners' of a vertex, i.e., 1.  Here for consistency
618         \return 1
619      */
Corners_Of_Elem(const UG_NS<UG_DIM>::Node * theNode)620     static int Corners_Of_Elem(const UG_NS< UG_DIM >::Node* theNode) {
621       return 1;
622     }
623 
624     //! Return number of corners of a given side
Corners_Of_Side(const UG_NS<UG_DIM>::Element * theElement,int side)625     static int Corners_Of_Side(const UG_NS< UG_DIM >::Element* theElement, int side) {
626       using UG_NAMESPACE ::element_descriptors;
627       using UG::UINT;
628       return CORNERS_OF_SIDE(theElement, side);
629     }
630 
631     //! Return local number of a given corner of a given element side
Corner_Of_Side(const UG_NS<UG_DIM>::Element * theElement,int side,int corner)632     static int Corner_Of_Side(const UG_NS< UG_DIM >::Element* theElement, int side, int corner) {
633       using UG_NAMESPACE ::element_descriptors;
634       using UG::UINT;
635       return CORNER_OF_SIDE(theElement, side, corner);
636     }
637 
638     //! Return local number of a given corner of a given element edge
Corner_Of_Edge(const UG_NS<UG_DIM>::Element * theElement,int edge,int corner)639     static int Corner_Of_Edge(const UG_NS< UG_DIM >::Element* theElement, int edge, int corner) {
640       using UG_NAMESPACE ::element_descriptors;
641       using UG::UINT;
642       return CORNER_OF_EDGE(theElement, edge, corner);
643     }
644 
645     //! Return number of sons of an element
nSons(const UG_NAMESPACE::element * element)646     static int nSons(const UG_NAMESPACE ::element* element) {
647       return UG_NAMESPACE ::ReadCW(element, UG_NAMESPACE ::NSONS_CE);
648     }
649 
GetSons(const UG_NAMESPACE::element * element,UG_NAMESPACE::element * sonList[MAX_SONS])650     static int GetSons(const UG_NAMESPACE ::element* element, UG_NAMESPACE ::element* sonList[MAX_SONS]) {
651       return UG_NAMESPACE ::GetSons(element, sonList);
652     }
653 
654     /** \todo Remove the const casts */
GetNodeContext(const UG_NAMESPACE::element * element,const UG_NAMESPACE::node ** context)655     static int GetNodeContext(const UG_NAMESPACE ::element* element, const UG_NAMESPACE ::node** context) {
656       return UG_NAMESPACE ::GetNodeContext(element, const_cast<UG_NAMESPACE ::node**>(context));
657     }
658 
659     //! Encapsulates the GRID_ATTR macro
Grid_Attr(const UG_NS<UG_DIM>::Grid * grid)660     static int Grid_Attr(const UG_NS< UG_DIM >::Grid* grid) {
661       return GRID_ATTR(grid);
662     }
663 
MarkForRefinement(UG_NAMESPACE::element * element,int rule,int data)664     static int MarkForRefinement(UG_NAMESPACE ::element* element, int rule, int data) {
665       return UG_NAMESPACE ::MarkForRefinement(element, (UG_NAMESPACE ::RefinementRule)rule, data);
666     }
667 
668     //! Encapsulates the TAG macro
Tag(const UG_NS<UG_DIM>::Element * theElement)669     static unsigned int Tag(const UG_NS< UG_DIM >::Element* theElement) {
670       using UG::UINT;
671       return TAG(theElement);
672     }
673 
674     //! Doesn't ever get called, but needs to be there to calm the compiler
Tag(const UG_NS<UG_DIM>::Node * theNode)675     static unsigned int Tag(const UG_NS< UG_DIM >::Node* theNode) {
676       DUNE_THROW(GridError, "Called method Tag() for a vertex.  This should never happen!");
677       return 0;
678     }
679 
680     //! get corner in local coordinates, corner number in UG's numbering system
681     template<class T>
getCornerLocal(const UG_NS<UG_DIM>::Element * theElement,int corner,FieldVector<T,UG_DIM> & local)682     static void  getCornerLocal (const UG_NS< UG_DIM >::Element* theElement, int corner, FieldVector<T, UG_DIM>& local)
683     {
684       using UG_NAMESPACE ::element_descriptors;
685       using UG::UINT;
686       for (int i=0; i<UG_DIM; i++)
687         local[i] = LOCAL_COORD_OF_TAG(TAG(theElement),corner)[i];
688     }
689 
690     //! Next element in the UG element lists
succ(const UG_NS<UG_DIM>::Element * theElement)691     static UG_NS< UG_DIM >::Element* succ(const UG_NS< UG_DIM >::Element* theElement) {
692       return theElement->ge.succ;
693     }
694 
695     //! Next element in the UG nodes lists
succ(const UG_NS<UG_DIM>::Node * theNode)696     static UG_NS< UG_DIM >::Node* succ(const UG_NS< UG_DIM >::Node* theNode) {
697       return theNode->succ;
698     }
699 
700     //! Calm the compiler
succ(const void * theWhatever)701     static void* succ(const void* theWhatever) {
702       DUNE_THROW(NotImplemented, "No successor available for this kind of object");
703       return 0;
704     }
705 
706     //! Return true if the element is a ghost element
707 #ifdef ModelP
isGhost(const UG_NS<UG_DIM>::Element * theElement)708     static bool isGhost(const UG_NS< UG_DIM >::Element* theElement) {
709       if (EPRIO(theElement) == PrioHGhost
710           || EPRIO(theElement) == PrioVGhost
711           || EPRIO(theElement) == PrioVHGhost)
712         return true;
713       else
714         return false;
715     }
716 #endif
717 
718     //! Return true if the element is a leaf element
isLeaf(const UG_NS<UG_DIM>::Element * theElement)719     static bool isLeaf(const UG_NS< UG_DIM >::Element* theElement) {
720       using UG ::UINT;
721       using UG_NAMESPACE ::CONTROL_ENTRY;
722       using UG_NAMESPACE ::control_entries;
723 
724       return LEAFELEM(theElement);
725     }
726 
727     //! Return true if the node is a leaf node
isLeaf(const UG_NS<UG_DIM>::Node * theNode)728     static bool isLeaf(const UG_NS< UG_DIM >::Node* theNode) {
729       return theNode->isLeaf;
730     }
731 
732     //! Return true if the edge is a leaf edge
isLeaf(const UG_NS<UG_DIM>::Edge * theEdge)733     static bool isLeaf(const UG_NS< UG_DIM >::Edge* theEdge) {
734       return theEdge->leafIndex > -1;
735     }
736 
737     //! Return true if the side vector is a leaf side vector
isLeaf(const UG_NS<UG_DIM>::Vector * theVector)738     static bool isLeaf(const UG_NS< UG_DIM >::Vector* theVector) {
739       using UG_NAMESPACE ::VECTOR;
740       using UG::UINT;
741       // Since the vector cannot be asked directly,
742       // the corresponding element is asked.
743       return isLeaf((UG_NS< UG_DIM >::Element*)VOBJECT(theVector));
744     }
745     // /////////////////////////////////////////////
746     //   Level indices
747     // /////////////////////////////////////////////
748 
749     //! Gets the level index of a UG element
levelIndex(UG_NS<UG_DIM>::Element * theElement)750     static int& levelIndex(UG_NS< UG_DIM >::Element* theElement) {
751       return theElement->ge.levelIndex;
752     }
753 
754     //! Gets the level index of a UG element
levelIndex(const UG_NS<UG_DIM>::Element * theElement)755     static const int& levelIndex(const UG_NS< UG_DIM >::Element* theElement) {
756       return theElement->ge.levelIndex;
757     }
758 
759     //! Gets the level index of a UG sidevector
levelIndex(Vector * theVector)760     static UG::UINT& levelIndex(Vector* theVector) {
761 #if UG_DIM == 2
762       DUNE_THROW(GridError, "levelIndex in side vector only in 3D!");
763 #endif
764       return theVector->index;
765     }
766 
767     //! Gets the level index of a UG sidevector
levelIndex(const Vector * theVector)768     static const UG::UINT& levelIndex(const Vector* theVector) {
769 #if UG_DIM == 2
770       DUNE_THROW(GridError, "levelIndex in side vector only in 3D!");
771 #endif
772       return theVector->index;
773     }
774 
775     //! Gets the level index of a UG edge
levelIndex(UG_NS<UG_DIM>::Edge * theEdge)776     static int& levelIndex(UG_NS< UG_DIM >::Edge* theEdge) {
777       return theEdge->levelIndex;
778     }
779 
780     //! Gets the level index of a UG edge
levelIndex(const UG_NS<UG_DIM>::Edge * theEdge)781     static const int& levelIndex(const UG_NS< UG_DIM >::Edge* theEdge) {
782       return theEdge->levelIndex;
783     }
784 
785     //! Gets the level index of a UG node
levelIndex(UG_NS<UG_DIM>::Node * theNode)786     static int& levelIndex(UG_NS< UG_DIM >::Node* theNode) {
787       return theNode->levelIndex;
788     }
789 
790     //! Gets the level index of a UG node
levelIndex(const UG_NS<UG_DIM>::Node * theNode)791     static const int& levelIndex(const UG_NS< UG_DIM >::Node* theNode) {
792       return theNode->levelIndex;
793     }
794 
795     // /////////////////////////////////////////////
796     //   Leaf indices
797     // /////////////////////////////////////////////
798 
799     //! Gets the leaf index of a UG element
leafIndex(UG_NS<UG_DIM>::Element * theElement)800     static int& leafIndex(UG_NS< UG_DIM >::Element* theElement) {
801       return theElement->ge.leafIndex;
802     }
803 
804     //! Gets the leaf index of a UG element
leafIndex(const UG_NS<UG_DIM>::Element * theElement)805     static const int& leafIndex(const UG_NS< UG_DIM >::Element* theElement) {
806       return theElement->ge.leafIndex;
807     }
808 
809     //! Gets the leaf index of a UG sidevector
leafIndex(Vector * theVector)810     static UG::UINT& leafIndex(Vector* theVector) {
811       return theVector->leafIndex;
812     }
813 
814     //! Gets the leaf index of a UG sidevector
leafIndex(const Vector * theVector)815     static const UG::UINT& leafIndex(const Vector* theVector) {
816       return theVector->leafIndex;
817     }
818 
819     //! Gets the leaf index of a UG edge
leafIndex(UG_NS<UG_DIM>::Edge * theEdge)820     static int& leafIndex(UG_NS< UG_DIM >::Edge* theEdge) {
821       return theEdge->leafIndex;
822     }
823 
824     //! Gets the leaf index of a UG edge
leafIndex(const UG_NS<UG_DIM>::Edge * theEdge)825     static const int& leafIndex(const UG_NS< UG_DIM >::Edge* theEdge) {
826       return theEdge->leafIndex;
827     }
828 
829     //! Gets the leaf index of a UG node
leafIndex(UG_NS<UG_DIM>::Node * theNode)830     static int& leafIndex(UG_NS< UG_DIM >::Node* theNode) {
831       return theNode->myvertex->iv.leafIndex;
832     }
833 
834     //! Gets the leaf index of a UG node
leafIndex(const UG_NS<UG_DIM>::Node * theNode)835     static const int& leafIndex(const UG_NS< UG_DIM >::Node* theNode) {
836       return theNode->myvertex->iv.leafIndex;
837     }
838 
839     // /////////////////////////////////////////////
840     //   IDs
841     // /////////////////////////////////////////////
842 
843     //! Gets the index of a UG element
id(const UG_NS<UG_DIM>::Element * theElement)844     static auto id(const UG_NS< UG_DIM >::Element* theElement) {
845 #if defined ModelP
846       return theElement->ge.ddd.gid;
847 #else
848       return theElement->ge.id;
849 #endif
850     }
851 
852     //! Gets the id of a UG facet
id(const UG_NS<UG_DIM>::Vector * theVector)853     static auto id(const UG_NS< UG_DIM >::Vector* theVector) {
854 #ifdef ModelP
855       return theVector->ddd.gid;
856 #else
857       auto id = theVector->id;
858 
859       // In sequential UG, two entities of different codimension can have the same id,
860       // so let's encode the codimension in the id to make them differ.
861       constexpr unsigned int codim = 1;  //
862       return id | (codim << 30);
863 #endif
864     }
865 
866     //! Gets the id of a UG edge
id(const UG_NS<UG_DIM>::Edge * theEdge)867     static auto id(const UG_NS< UG_DIM >::Edge* theEdge) {
868 #ifdef ModelP
869       return theEdge->ddd.gid;
870 #else
871       auto id = theEdge->id;
872 
873       // In sequential UG, two entities of different codimension can have the same id,
874       // so let's encode the codimension in the id to make them differ.
875       constexpr unsigned int codim = UG_DIM-1;  //
876       return id | (codim << 30);
877 #endif
878     }
879 
880     //! Gets the index of a UG node
id(const UG_NS<UG_DIM>::Node * theNode)881     static auto id(const UG_NS< UG_DIM >::Node* theNode) {
882 #ifdef ModelP
883       return theNode->myvertex->iv.ddd.gid;
884 #else
885       auto id = theNode->myvertex->iv.id;
886 
887       // In sequential UG, two entities of different codimension can have the same id,
888       // so let's encode the codimension in the id to make them differ.
889       constexpr unsigned int codim = UG_DIM;
890       return id | (codim << 30);
891 #endif
892     }
893 
894     /** \brief Compute global coordinates of a point in local coordinates for an element */
Local_To_Global(int n,double ** y,const FieldVector<double,UG_DIM> & local,FieldVector<double,UG_DIM> & global)895     static void Local_To_Global(int n, double** y,
896                                 const FieldVector<double, UG_DIM>& local,
897                                 FieldVector<double, UG_DIM>& global) {
898       using UG::DOUBLE;
899       LOCAL_TO_GLOBAL(n,y,local,global);
900     }
901 
902     /** \brief Compute global coordinates of a point in local coordinates for a vertex */
Local_To_Global(int n,double ** y,const FieldVector<double,0> & local,FieldVector<double,UG_DIM> & global)903     static void Local_To_Global(int n, double** y,
904                                 const FieldVector<double,0>& local,
905                                 FieldVector<double, UG_DIM>& global) {
906       for (int i=0; i<UG_DIM; i++)
907         global[i] = y[0][i];
908     }
909 
910     /**
911      * \param n Number of corners of the element
912      * \param x Coordinates of the corners of the element
913      * \param local Local evaluation point
914      *
915      * \return The return type is int because the macro INVERSE_TRANSFORMATION
916      *  returns 1 on failure.
917      */
Transformation(int n,double ** x,const FieldVector<double,UG_DIM> & local,FieldMatrix<double,UG_DIM,UG_DIM> & mat)918     static int Transformation(int n, double** x,
919                               const FieldVector<double, UG_DIM>& local, FieldMatrix<double,UG_DIM,UG_DIM>& mat) {
920       using UG_NAMESPACE ::DOUBLE_VECTOR;
921       using UG::DOUBLE;
922       double det;
923 #ifndef SMALL_D
924       const double SMALL_D = DBL_EPSILON*10;
925 #endif
926       INVERSE_TRANSFORMATION(n, x, local, mat, det);
927       return 0;
928     }
929 
930     /** \brief Dummy method for vertices */
Transformation(int n,double ** x,const FieldVector<double,0> & local,FieldMatrix<double,UG_DIM,0> & mat)931     static int Transformation(int n, double** x,
932                               const FieldVector<double, 0>& local, FieldMatrix<double,UG_DIM,0>& mat) {
933       return 0;
934     }
935 
936     /**
937      * \param n Number of corners of the element
938      * \param x Coordinates of the corners of the element
939      * \param local Local evaluation point
940      *
941      * \return The return type is int because the macro TRANSFORMATION
942      *  returns 1 on failure.
943      */
JacobianTransformation(int n,double ** x,const FieldVector<double,UG_DIM> & local,FieldMatrix<double,UG_DIM,UG_DIM> & mat)944     static int JacobianTransformation(int n, double** x,
945                                       const FieldVector<double, UG_DIM>& local, FieldMatrix<double,UG_DIM,UG_DIM>& mat) {
946       using UG_NAMESPACE ::DOUBLE_VECTOR;
947       using UG::DOUBLE;
948       TRANSFORMATION(n, x, local, mat);
949       return 0;
950     }
951 
952     /** \brief Dummy method for vertices */
JacobianTransformation(int n,double ** x,const FieldVector<double,0> & local,FieldMatrix<double,0,UG_DIM> & mat)953     static int JacobianTransformation(int n, double** x,
954                                       const FieldVector<double, 0>& local, FieldMatrix<double,0,UG_DIM>& mat) {
955       return 0;
956     }
957 
958     //! Returns the i-th corner of a UG element
Corner(const UG_NS<UG_DIM>::Element * theElement,int i)959     static UG_NS< UG_DIM >::Node* Corner(const UG_NS< UG_DIM >::Element* theElement, int i) {
960       using UG_NAMESPACE ::NODE;
961       using UG_NAMESPACE ::n_offset;
962       using UG::UINT;
963       return CORNER(theElement, i);
964     }
965 
966     //! Returns the i-th edge of a UG element
ElementEdge(const UG_NS<UG_DIM>::Element * theElement,int i)967     static UG_NS< UG_DIM >::Edge* ElementEdge(const UG_NS< UG_DIM >::Element* theElement, int i) {
968       using UG_NAMESPACE ::NODE;
969       using UG_NAMESPACE ::n_offset;
970       using UG::UINT;
971       using UG_NAMESPACE ::element_descriptors;
972       return GetEdge(CORNER(theElement, CORNER_OF_EDGE(theElement, i, 0)),
973                      CORNER(theElement, CORNER_OF_EDGE(theElement, i, 1)));
974     }
975 
976     //! get edge from node i to node j (in UG's numbering !
GetEdge(UG_NS<UG_DIM>::Node * nodei,UG_NS<UG_DIM>::Node * nodej)977     static UG_NS< UG_DIM >::Edge* GetEdge (UG_NS< UG_DIM >::Node* nodei, UG_NS< UG_DIM >::Node* nodej) {
978       return UG_NAMESPACE ::GetEdge(nodei,nodej);
979     }
980 
981     //! access side vector from element (this is just a dummy to compile code also in 2d)
SideVector(const UG_NS<UG_DIM>::Element * theElement,int i)982     static Vector* SideVector (const UG_NS< UG_DIM >::Element* theElement, int i)
983     {
984 #if UG_DIM == 2
985       DUNE_THROW(GridError, "side vector only in 3D!");
986 #else
987       using UG::D3::VECTOR;
988       using UG::D3::svector_offset;
989       using UG::UINT;
990       return SVECTOR(theElement,i);
991 #endif
992     }
993 
994     //! Access element from side vector
GetElementAndSideFromSideVector(const UG_NS<UG_DIM>::Vector * theVector,UG_NS<UG_DIM>::Element * & theElement,unsigned int & side)995     static void GetElementAndSideFromSideVector(const UG_NS< UG_DIM >::Vector* theVector,
996                                                 UG_NS< UG_DIM >::Element*& theElement,
997                                                 unsigned int& side)
998     {
999       using UG_NAMESPACE ::VECTOR;
1000       using UG::UINT;
1001 
1002       theElement = (UG_NS< UG_DIM >::Element*)VOBJECT(theVector);
1003       side = VECTORSIDE(theVector);
1004     }
1005 
1006     /** \brief Return a pointer to the father of the given element */
EFather(const UG_NS<UG_DIM>::Element * theElement)1007     static UG_NS< UG_DIM >::Element* EFather(const UG_NS< UG_DIM >::Element* theElement) {
1008       using UG_NAMESPACE ::ELEMENT;
1009       using UG_NAMESPACE ::father_offset;
1010       using UG::UINT;
1011       return EFATHER(theElement);
1012     }
1013 
1014     //! get father element of vertex
NFather(UG_NS<UG_DIM>::Node * theNode)1015     static UG_NS< UG_DIM >::Element* NFather(UG_NS< UG_DIM >::Node* theNode) {
1016       return theNode->myvertex->iv.father;
1017     }
1018 
1019     //! get father node of vertex
NodeNodeFather(UG_NS<UG_DIM>::Node * theNode)1020     static UG_NS< UG_DIM >::Node* NodeNodeFather(UG_NS< UG_DIM >::Node* theNode) {
1021       using UG_NAMESPACE ::NDOBJ;
1022       using UG_NAMESPACE ::GM_OBJECTS;
1023       using UG::UINT;
1024       if (theNode->father==0)
1025         return 0;         // no father at all
1026       if (OBJT(theNode->father)==NDOBJ)
1027         return (UG_NAMESPACE ::node*) theNode->father;
1028       else
1029         return 0;         // may be edge or element
1030     }
1031 
ReadCW(void * obj,int ce)1032     static unsigned int ReadCW(void* obj, int ce) {
1033       return UG_NAMESPACE ::ReadCW(obj, ce);
1034     }
1035 
WriteCW(void * obj,int ce,int n)1036     static void WriteCW(void* obj, int ce, int n) {
1037       UG_NAMESPACE ::WriteCW(obj, ce, n);
1038     }
1039 
1040     //! \todo Please doc me!
InitUg(int * argcp,char *** argvp)1041     static int InitUg(int* argcp, char*** argvp) {
1042       return UG_NAMESPACE ::InitUg(argcp, argvp);
1043     }
1044 
ExitUg()1045     static void ExitUg() {
1046       UG_NAMESPACE ::ExitUg();
1047     }
1048 
DisposeMultiGrid(UG_NAMESPACE::multigrid * mg)1049     static int DisposeMultiGrid(UG_NAMESPACE ::multigrid* mg) {
1050       return UG_NAMESPACE ::DisposeMultiGrid(mg);
1051     }
1052 
1053     //! \todo Please doc me!
CreateBoundaryValueProblem(const char * BVPname,int numOfCoeffFunc,UG_NAMESPACE::CoeffProcPtr coeffs[],int numOfUserFct,UG_NAMESPACE::UserProcPtr userfct[])1054     static void* CreateBoundaryValueProblem(const char* BVPname,
1055                                             int numOfCoeffFunc,
1056                                             UG_NAMESPACE ::CoeffProcPtr coeffs[],
1057                                             int numOfUserFct,
1058                                             UG_NAMESPACE ::UserProcPtr userfct[]) {
1059       return UG_NAMESPACE ::CreateBoundaryValueProblem(BVPname, 0, numOfCoeffFunc, coeffs,
1060                                                        numOfUserFct, userfct);
1061     }
1062 
1063     //! Set the current boundary value problem
Set_Current_BVP(void ** thisBVP)1064     static void Set_Current_BVP(void** thisBVP) {
1065       UG_NAMESPACE ::Set_Current_BVP(thisBVP);
1066     }
1067 
1068     //! Get UG boundary value problem from its name
BVP_GetByName(const char * name)1069     static void** BVP_GetByName(const char* name) {
1070       return UG_NAMESPACE ::BVP_GetByName(name);
1071     }
1072 
1073     //! Dispose of a boundary value problem
BVP_Dispose(void ** BVP)1074     static int BVP_Dispose(void** BVP) {
1075       return UG_NAMESPACE ::BVP_Dispose(BVP);
1076     }
1077 
1078     /** \brief Create new point on the grid boundary by giving local coordinates.
1079 
1080        Global coordinates are computed automatically using the domain boundary information.
1081        The point is not inserted as a new vertex in the grid!
1082      */
BNDP_CreateBndP(UG::HEAP * Heap,BNDP * theBndP0,BNDP * theBndP1,UG::DOUBLE lcoord)1083     static BNDP *BNDP_CreateBndP(UG::HEAP *Heap,
1084                                  BNDP *theBndP0,
1085                                  BNDP *theBndP1,
1086                                  UG::DOUBLE lcoord) {
1087       return UG_NAMESPACE::BNDP_CreateBndP(Heap, theBndP0, theBndP1, lcoord);
1088     }
1089 
1090     /** \brief Get global position of a point on the grid boundary */
BNDP_Global(BNDP * theBndP,UG::DOUBLE * global)1091     static UG::INT BNDP_Global(BNDP *theBndP,
1092                                UG::DOUBLE *global) {
1093       return UG_NAMESPACE::BNDP_Global(theBndP, global);
1094     }
1095 
1096     /** \brief Delete a grid boundary point */
BNDP_Dispose(UG::HEAP * Heap,BNDP * theBndP)1097     static UG::INT BNDP_Dispose(UG::HEAP *Heap,
1098                                 BNDP *theBndP) {
1099       return UG_NAMESPACE::BNDP_Dispose(Heap, theBndP);
1100     }
1101 
1102     //! Get UG multigrid object from its name
GetMultigrid(const char * name)1103     static UG_NS< UG_DIM >::MultiGrid* GetMultigrid(const char* name) {
1104       return UG_NAMESPACE ::GetMultigrid(name);
1105     }
1106 
1107     /** \brief Load-balance the grid by recursive coordinate bisection */
lbs(const char * argv,UG_NAMESPACE::multigrid * theMG)1108     static void lbs(const char *argv, UG_NAMESPACE ::multigrid *theMG) {
1109 #ifdef ModelP
1110       return UG_NAMESPACE ::lbs(argv, theMG);
1111 #endif
1112     }
1113 
1114     //! An UG-internal load balancing method
TransferGridFromLevel(UG_NAMESPACE::multigrid * theMG,int level)1115     static int TransferGridFromLevel(UG_NAMESPACE ::multigrid *theMG, int level) {
1116 #ifdef ModelP
1117       return UG_NAMESPACE ::TransferGridFromLevel(theMG,level);
1118 #else
1119       return 0;
1120 #endif
1121     }
1122 
CreateMultiGrid(const char * MultigridName,const char * BndValProblem,const char * format,int optimizedIE,int insertMesh,std::shared_ptr<PPIF::PPIFContext> ppifContext=nullptr)1123     static MultiGrid *CreateMultiGrid(const char *MultigridName, const char *BndValProblem,
1124                                       const char *format,
1125                                       int optimizedIE, int insertMesh,
1126                                       std::shared_ptr<PPIF::PPIFContext> ppifContext = nullptr) {
1127       return UG_NAMESPACE ::CreateMultiGrid(const_cast<char*>(MultigridName),
1128                                             const_cast<char*>(BndValProblem), format,
1129                                             optimizedIE, insertMesh, ppifContext);
1130     }
1131 
CreateDomain(const char * name,int segments,int corners)1132     static void* CreateDomain(const char* name, int segments, int corners) {
1133       return UG_NAMESPACE ::CreateDomain(name, segments, corners);
1134     }
1135 
RemoveDomain(const char * name)1136     static void RemoveDomain(const char* name) {
1137       UG_NAMESPACE ::RemoveDomain(name);
1138     }
1139 
InsertInnerNode(UG_NAMESPACE::grid * grid,const double * pos)1140     static void* InsertInnerNode(UG_NAMESPACE ::grid* grid, const double* pos) {
1141       return UG_NAMESPACE ::InsertInnerNode(grid, pos);
1142     }
1143 
CreateBoundarySegment(const char * name,int left,int right,int index,UG::INT * point,const double * alpha,const double * beta,UG_NAMESPACE::BndSegFuncPtr boundarySegmentFunction,void * userData)1144     static void* CreateBoundarySegment(const char *name, int left, int right,
1145                                        int index,
1146                                        UG::INT *point,
1147                                        const double *alpha, const double *beta,
1148                                        UG_NAMESPACE ::BndSegFuncPtr boundarySegmentFunction,
1149                                        void *userData) {
1150       return UG_NAMESPACE ::CreateBoundarySegment(name,            // internal name of the boundary segment
1151                                                   left,             //  id of left subdomain
1152                                                   right,             //  id of right subdomain
1153                                                   index,         // Index of the segment
1154                                                   UG_NAMESPACE ::NON_PERIODIC, // I don't know what this means
1155                                                   point,
1156                                                   alpha,
1157                                                   beta,
1158                                                   boundarySegmentFunction,
1159                                                   userData);
1160     }
1161 
CreateLinearSegment(const char * name,int left,int right,int index,int numVertices,const UG::INT * cornerIndices,double cornerCoordinates[2][UG_DIM])1162     static void* CreateLinearSegment(const char *name,
1163                                      int left, int right,
1164                                      int index, int numVertices,
1165                                      const UG::INT* cornerIndices,
1166                                      double cornerCoordinates[2][ UG_DIM ])
1167     {
1168       return UG_NAMESPACE ::CreateLinearSegment(name,            // internal name of the boundary segment
1169                                                 left,            //  id of left subdomain
1170                                                 right,           //  id of right subdomain
1171                                                 index,           // Index of the segment
1172                                                 numVertices,
1173                                                 cornerIndices,
1174                                                 cornerCoordinates);
1175     }
1176 
1177   };
1178 
1179   template <>
1180   class UG_NS< UG_DIM >::Entity<0>
1181   {
1182   public:
1183     typedef UG_NAMESPACE ::element T;
1184   };
1185 
1186   template <>
1187   class UG_NS< UG_DIM >::Entity< UG_DIM - 1 >
1188   {
1189   public:
1190     typedef UG_NAMESPACE ::edge T;
1191   };
1192 
1193 #if UG_DIM == 3
1194   template <>
1195   class UG_NS< UG_DIM >::Entity<1>
1196   {
1197   public:
1198     typedef UG_NAMESPACE ::vector T;
1199   };
1200 #endif
1201 
1202   template <>
1203   class UG_NS< UG_DIM >::Entity< UG_DIM > {
1204   public:
1205     typedef UG_NAMESPACE ::node T;
1206   };
1207 
1208 #undef UG_NAMESPACE
1209 
1210 } // namespace Dune
1211