1 #include <config.h>
2 #include <iostream>
3 #include <set>
4 
5 #include <dune/grid/common/gridinfo.hh>
6 
7 #include <dune/fem/gridpart/leafgridpart.hh>
8 #include <dune/fem/io/parameter.hh>
9 #include <dune/fem/quadrature/cachingquadrature.hh>
10 #include <dune/fem/quadrature/elementquadrature.hh>
11 #include <dune/fem/quadrature/agglomerationquadrature.hh>
12 
13 #include <dune/fem/quadrature/dunequadratures.hh>
14 #include <dune/fem/quadrature/lumpingquadrature.hh>
15 
16 #include "checkleafcodim1.hh"
17 
18 using namespace Dune;
19 using namespace Fem ;
20 
21 struct DuneQuadratures
22 {};
23 
24 template<class GridPartType, bool caching, class QuadratureTraits = int>
25 class TestCaching
26 {
27 private:
28   // types of iterators, entities and intersection
29   typedef typename GridPartType :: template Codim<0> :: IteratorType IteratorType;
30   typedef typename GridPartType :: IndexSetType  IndexSetType ;
31   typedef typename IteratorType :: Entity EntityType;
32   typedef typename EntityType :: Geometry  Geometry;
33   typedef typename GridPartType :: IntersectionIteratorType IntersectionIteratorType;
34   typedef typename IntersectionIteratorType :: Intersection IntersectionType;
35 
36   typedef Dune::Fem::ElementQuadrature<GridPartType, 0>    ElementQuadratureType;
37 
38   typedef CachingLumpingQuadrature< GridPartType, 0> LumpingQuadratureType;
39 
40   GridPartType & gridPart_;
41   int order_;
42   const double eps_;
43   const bool skipFaces_;
44 
45 public:
46 
TestCaching(GridPartType & gridPart,int order,const double eps=1e-8)47   TestCaching(GridPartType & gridPart, int order, const double eps = 1e-8)
48     : gridPart_(gridPart), order_( std::abs(order) ), eps_(eps), skipFaces_( order < 0 )
49   { }
50 
runTest()51   void runTest()
52   {
53     testElementQuadratures();
54   }
55 
56   template <class Coordinate>
function(const Coordinate & x) const57   double function( const Coordinate& x ) const
58   {
59     return x * x;
60   }
61 
testElementQuadratures()62   void testElementQuadratures()
63   {
64     IteratorType endit = gridPart_.template end<0>();
65     for (IteratorType it = gridPart_.template begin<0>(); it != endit; ++it)
66     {
67       const EntityType & entity = *it;
68       const Geometry& geo = entity.geometry();
69       const double volume = geo.volume();
70 
71 
72       // test integration of 1 over element which should yield the volume.
73       double integral = 0 ;
74       {
75         // test memory management of agglomeration
76         {
77           ElementQuadratureType quad1( entity, order_, false );
78           ElementQuadratureType quad2( entity, order_, false );
79         }
80         // false here forces the weights and points to be computed
81         ElementQuadratureType quad( entity, order_, false );
82         const int quadNop = quad.nop();
83         // integrate function over element
84         for( int qp=0; qp<quadNop; ++qp )
85         {
86           integral += quad.weight( qp ) * geo.integrationElement( quad.point( qp ) );
87         }
88 
89         if( std::abs( integral - volume ) > 1e-8 )
90         {
91           DUNE_THROW(InvalidStateException,"Integral of 1 of element does not yield the volume. Int = " << integral << " vol = " << volume );
92         }
93 
94         // test integration of function over element and compare with normal
95         // quadrature
96         integral = 0;
97         // integrate function over element
98         for( int qp=0; qp<quadNop; ++qp )
99         {
100           double val = function( geo.global( quad.point( qp ) ) );
101           integral += val * quad.weight( qp ) * geo.integrationElement( quad.point( qp ) );
102         }
103       }
104 
105       double checkInt = 0;
106       {
107         // this only works with regular elements
108         assert( ! entity.type().isNone() );
109         ElementQuadratureType elemQuad( entity, order_ );
110         const int qNop = elemQuad.nop();
111         // integrate function over element
112         for( int qp=0; qp<qNop; ++qp )
113         {
114           double val = function( geo.global( elemQuad.point( qp ) ) );
115           checkInt += val * elemQuad.weight( qp ) * geo.integrationElement( elemQuad.point( qp ) );
116         }
117       }
118 
119       if( std::abs( integral - checkInt ) > 1e-8 )
120       {
121         DUNE_THROW(InvalidStateException,"Integral does not equal check! Int = " << integral << " check = " << checkInt );
122       }
123     }
124   }
125 
126 };
127 
128 // main program
main(int argc,char ** argv)129 int main(int argc, char ** argv)
130 {
131   try
132   {
133     MPIManager :: initialize( argc, argv );
134     // *** Initialization
135     Parameter::append(argc, argv);
136     if (argc==2) Parameter::append(argv[1]);
137     else Parameter::append("parameter");
138 
139     typedef Dune::GridSelector::GridType GridType;
140     std::string filename;
141     std::stringstream fileKey ;
142     fileKey << "fem.gridfile" << GridType :: dimension ;
143     Parameter::get( fileKey.str(), filename);
144     Dune::GridPtr< GridType > gridptr( filename );
145     GridType &grid = *gridptr;
146 
147     int maxlevel = 0; // Parameter::getValue<int>("fem.maxlevel");
148     //grid.globalRefine( maxlevel );
149     //Dune::gridinfo(grid);
150 
151     int quadOrder = 2;//Parameter::getValue<int>("fem.quadorder");
152 
153     if ( Parameter::getValue<bool>("fem.skipfaces", false ) )
154       quadOrder = -quadOrder ;
155 
156     int nonConformOrigin = Parameter::getValue< int > ( "poisson.nonConformOrigin", 0 );
157     if ( nonConformOrigin )
158     {
159       const int refineelement = 1 ;
160       std::cout << "Create local refined grid" << std::endl;
161       for (int i=0;i<nonConformOrigin;++i)
162       {
163         if( grid.comm().rank() == 0)
164         {
165           typedef GridType::Codim<0>::LeafIterator IteratorType;
166           IteratorType endit = grid.leafend<0>();
167           for(IteratorType it = grid.leafbegin<0>(); it != endit ; ++it)
168           {
169             const IteratorType :: Entity & entity = *it ;
170             const IteratorType :: Entity :: Geometry& geo = entity.geometry();
171             if (geo.center().two_norm() < 0.5)
172             {
173               grid.mark(refineelement, entity );
174               std::cout << "mark" << std::endl;
175             }
176           }
177         }
178         grid.preAdapt();
179         grid.adapt();
180         grid.postAdapt();
181       }
182     }
183 
184     //typedef HierarchicGridPart< GridType > GridPartType;
185     typedef Dune::Fem::LeafGridPart< GridType > GridPartType;
186     GridPartType gridPart( grid );
187 
188     const double eps = 1e-8;
189 
190     for(int l=0; l<=maxlevel; ++l )
191     {
192       {
193         std::cout << "Testing AgglomerationQuadratures: " << std::endl;
194         TestCaching<GridPartType,false> testCaching(gridPart, quadOrder, eps);
195         testCaching.runTest();
196       }
197       grid.globalRefine( 1 );
198     }
199     return 0;
200   }
201   catch( const Exception& e )
202   {
203     std :: cerr << e.what() << std :: endl;
204     return 1;
205   }
206 }
207