1 #ifndef DUNE_CARTESIANGRID_HOSTGRIDINFO_ALUGRID_HH
2 #define DUNE_CARTESIANGRID_HOSTGRIDINFO_ALUGRID_HH
3 
4 #include <dune/common/fvector.hh>
5 
6 #if HAVE_DUNE_ALUGRID
7 #include <dune/alugrid/common/declaration.hh>
8 #include <dune/alugrid/3d/topology.hh>
9 #endif // #if HAVE_DUNE_ALUGRID
10 
11 namespace Dune
12 {
13 
14   // Internal Forward Declarations
15   // -----------------------------
16 
17   template< class HostGrid >
18   struct CartesianGridHostGridInfo;
19 
20   // ALU3dCubeOrigin
21   // ---------------
22 
23   template< class HostGrid, int dimension, int codimension >
24   struct ALU3dCubeOrigin
25   {
26     typedef typename HostGrid::template Codim< codimension >::Geometry::GlobalCoordinate OriginReturnType;
27 
28     template< class Item >
getDune::ALU3dCubeOrigin29     static OriginReturnType get ( const Item &item )
30     {
31       return item.geometry().corner( 0 );
32     }
33   };
34 
35   // for vertices
36   template< class HostGrid, int dimension >
37   struct ALU3dCubeOrigin< HostGrid, dimension, dimension >
38   {
39     typedef double coord_t[ dimension ];
40     typedef const coord_t &OriginReturnType;
41 
42     template< class Item >
getDune::ALU3dCubeOrigin43     static OriginReturnType get ( const Item &item )
44     {
45       return item.impl().getItem().Point();
46     }
47   };
48 
49   // for elements
50   template< class HostGrid, int dimension >
51   struct ALU3dCubeOrigin< HostGrid, dimension, 0 >
52   {
53     typedef double coord_t[ dimension ];
54     typedef const coord_t &OriginReturnType;
55 
56     template< class Item >
getDune::ALU3dCubeOrigin57     static OriginReturnType get ( const Item &item )
58     {
59       return item.impl().getItem().myvertex( 0 )->Point();
60     }
61   };
62 
63   // specialization for intersections
64   template< class HostGrid, int dimension >
65   struct ALU3dCubeOrigin< HostGrid, dimension, -1 >
66   {
67     typedef double coord_t[ dimension ];
68     typedef const coord_t &OriginReturnType;
69 
70     template< class Intersection >
getDune::ALU3dCubeOrigin71     static OriginReturnType get ( const Intersection &intersection )
72     {
73 #ifndef NDEBUG
74       typedef FaceTopologyMapping< hexa > CubeFaceMapping;
75       const int duneTwist = intersection.impl().twistInInside();
76       const int twistedIndex = CubeFaceMapping::twistedDuneIndex( 0, duneTwist );
77       assert( twistedIndex == 0 );
78 #endif
79       return intersection.impl().it().getItem().myvertex( 0 )->Point();
80     }
81   };
82 
83 
84 
85   // CartesianGridHostGridInfo for ALUGrid and dimension 3
86   // -----------------------------------------------------
87 
88   template< class HostGrid, int dim >
89   struct ALUGridHostGridInfo;
90 
91   template < class HostGrid >
92   struct ALUGridHostGridInfo< HostGrid, 3 >
93   {
94     static const int dimension = 3;
95 
96     //////////////////////////////////////////////////
97     //  direction methods
98     //////////////////////////////////////////////////
99 
100     //! default direction for given dimension
defaultDirectionDune::ALUGridHostGridInfo101     static unsigned int defaultDirection ( const int mydimension )
102     {
103       return (1 << mydimension)-1;
104     }
105 
106     //! direction for face i
directionDune::ALUGridHostGridInfo107     static unsigned int direction ( const int i, const int dimension )
108     {
109       assert( (i >= 0) && (i < 2*dimension) );
110       return (1 << (i / 2)) ^ ((1 << dimension) - 1);
111     }
112 
113     //! direction for given host entity
114     template< class HostEntity >
directionDune::ALUGridHostGridInfo115     static unsigned int direction ( const HostEntity& hostEntity )
116     {
117       typedef typename HostEntity::Geometry HostGeometry;
118       unsigned int direction = 0;
119       const HostGeometry &geo = hostEntity.geometry();
120       const typename HostGeometry::GlobalCoordinate origin = geo.corner( 0 );
121       for( int d = 0; d <HostGeometry::mydimension; ++d )
122       {
123         const typename HostGeometry::GlobalCoordinate point = geo.corner( 1 << d );
124         for( int i = 0; i < HostGeometry::coorddimension; ++i )
125         {
126           if( std::abs( point[ i ] - origin[ i ] ) > 1e-8 )
127             direction |= (1 << i);
128         }
129       }
130       return direction;
131     }
132 
133     //! default origin
defaultOriginDune::ALUGridHostGridInfo134     static FieldVector< double, dimension > defaultOrigin ()
135     {
136       return FieldVector< double, dimension >( 0 );
137     }
138 
139     //! origin for given entity or intersection
140     template< class HostItem >
141     static typename ALU3dCubeOrigin< HostGrid, HostItem::dimension, HostItem::codimension >::OriginReturnType
originDune::ALUGridHostGridInfo142     origin ( const HostItem &hostItem )
143     {
144       return ALU3dCubeOrigin< HostGrid, HostItem::dimension, HostItem::codimension >::get( hostItem );
145     }
146 
147     //! origin for given entity or intersection
148     template< class HostItem >
149     static typename ALU3dCubeOrigin< HostGrid, HostGrid::dimension, -1 >::OriginReturnType
originIntersectionDune::ALUGridHostGridInfo150     originIntersection ( const HostItem &hostItem )
151     {
152       return ALU3dCubeOrigin< HostGrid, HostGrid::dimension, -1 >::get( hostItem );
153     }
154 
155     //////////////////////////////////////////////////////////
156     //  child index methods
157     //////////////////////////////////////////////////////////
158 
159     //! return child index for entity
160     template< class HostEntity >
childIndexDune::ALUGridHostGridInfo161     static int childIndex ( const HostEntity &hostEntity )
162     {
163       // apply the same change as for the vertices of the hexa
164       typedef ElementTopologyMapping< hexa > ElemTopo;
165       return ElemTopo::alu2duneVertex( hostEntity.impl().getItem().nChild() );
166     }
167 
168     //////////////////////////////////////////////////////////
169     //  level methods
170     //////////////////////////////////////////////////////////
171 
172     //! return inside level for intersection
173     template <class HostIntersection>
insideLevelDune::ALUGridHostGridInfo174     static int insideLevel ( const HostIntersection &hostIntersection )
175     {
176 #ifndef NDEBUG
177       const int level = hostIntersection.impl().level();
178       const int insideLevel = hostIntersection.inside().level() ;
179       //assert( level == insideLevel );
180 #endif
181       return hostIntersection.impl().level();
182     }
183 
184     //! return outside level for intersection
185     template< class HostIntersection >
outsideLevelDune::ALUGridHostGridInfo186     static int outsideLevel ( const HostIntersection &hostIntersection,
187                               const int insideLevel )
188     {
189       // outsideLevel might be less than insideLevel if there is no level neighbor
190       const int outsideLevel = hostIntersection.impl().it().outsideLevel();
191       assert( !hostIntersection.neighbor() || (outsideLevel == hostIntersection.outside().level()) );
192       return outsideLevel;
193     }
194 
195     template< class HostIntersection >
childIndexInInsideDune::ALUGridHostGridInfo196     static int childIndexInInside ( const HostIntersection &hostIntersection,
197                                     const int insideLevel,
198                                     const int outsideLevel )
199     {
200       return getIntersectionChildLevel( hostIntersection.impl().twistInInside(),
201                                         hostIntersection.impl().it().getItem().nChild(),
202                                         insideLevel, outsideLevel );
203     }
204 
205     template< class HostIntersection >
childIndexInOutsideDune::ALUGridHostGridInfo206     static int childIndexInOutside ( const HostIntersection &hostIntersection,
207                                      const int insideLevel,
208                                      const int outsideLevel )
209     {
210       return getIntersectionChildLevel( hostIntersection.impl().twistInOutside(),
211                                         hostIntersection.impl().it().getItem().nChild(),
212                                         outsideLevel, insideLevel );
213     }
214 
215   protected:
216     static int
getIntersectionChildLevelDune::ALUGridHostGridInfo217     getIntersectionChildLevel( const int duneTwist, const int child,
218                                const int myLevel, const int otherLevel )
219     {
220       // make sure non-confoming level difference is at most 1
221       assert( std::abs( myLevel - otherLevel ) <= 1 );
222       if( myLevel < otherLevel )
223       {
224         // swap children 2 and 3
225         static const int map[4] = { 0, 1, 3, 2 };
226         return map[ child ];
227       }
228       else
229         return -1;
230     }
231   };
232 
233   // CartesianGridHostGridInfo for ALUGrid< 3, 3, cube, nonconforming, Comm >
234   // -------------------------------------------------------------------------
235 #if HAVE_DUNE_ALUGRID
236   template< class Comm >
237   struct CartesianGridHostGridInfo< ALUGrid< 3, 3, cube, nonconforming, Comm > >
238   : public ALUGridHostGridInfo< ALUGrid< 3, 3, cube, nonconforming, Comm >, 3 >
239   {};
240 #endif // #if HAVE_DUNE_ALUGRID
241 
242 } // namespace Dune
243 
244 
245 #endif // #ifndef DUNE_CARTESIANGRID_HOSTGRIDINFO_HH
246