1 //***********************************************************************
2 //
3 //  Example program how to use ALUGrid.
4 //  Author: Robert Kloefkorn
5 //
6 //  This little program read one of the macrogrids and generates a grid.
7 //  The  grid is refined and coarsend again.
8 //
9 //***********************************************************************
10 #include <config.h>
11 #include <iostream>
12 #include <stdlib.h>
13 #include <time.h>
14 
15 // include serial part of ALUGrid
16 #include <dune/alugrid/3d/alu3dinclude.hh>
17 
18 
19 //using namespace ALUGrid;
20 //using namespace std;
21 
22 typedef ALUGrid::Gitter::AdaptRestrictProlong AdaptRestrictProlongType;
23 
24 typedef ALUGrid::Gitter::helement_STI  HElemType;    // Interface Element
25 typedef ALUGrid::Gitter::hface_STI     HFaceType;    // Interface Element
26 typedef ALUGrid::Gitter::hedge_STI     HEdgeType;    // Interface Element
27 typedef ALUGrid::Gitter::vertex_STI    HVertexType;  // Interface Element
28 typedef ALUGrid::Gitter::hbndseg       HGhostType;
29 
30 #if HAVE_MPI
31 #warning RUNNING PARALLEL VERSION
32 #endif
33 
34 
35 //#define ENABLE_ALUGRID_VTK_OUTPUT
36 
37 struct EmptyGatherScatter : public ALUGrid::GatherScatter
38 {
39   typedef ALUGrid::GatherScatter :: ObjectStreamType  ObjectStreamType;
40   const int _rank;
41   const int _size;
42   const bool _userPartitioning;
43 
EmptyGatherScatterEmptyGatherScatter44   EmptyGatherScatter (const int rank, const int size, const bool useUserPart )
45     : _rank( rank ), _size( size ), _userPartitioning( useUserPart ) {}
46 
userDefinedPartitioningEmptyGatherScatter47   virtual bool userDefinedPartitioning () const { return _userPartitioning; }
userDefinedLoadWeightsEmptyGatherScatter48   virtual bool userDefinedLoadWeights  () const { return false ; }
repartitionEmptyGatherScatter49   virtual bool repartition () { return true ; }
destinationEmptyGatherScatter50   virtual int destination( const ALUGrid::Gitter::helement_STI &elem ) const
51   {
52     return _rank < (_size-1) ? _rank+1 : 0 ;
53   }
54 
hasUserDataEmptyGatherScatter55   bool hasUserData () const { return true; }
56 
containsEmptyGatherScatter57   bool contains ( int, int ) const { return true ;}
58 
inlineDataEmptyGatherScatter59   virtual void inlineData ( ObjectStreamType & str , HElemType & elem, const int ) {}
xtractDataEmptyGatherScatter60   virtual void xtractData ( ObjectStreamType & str , HElemType & elem ) {}
61 };
62 
63 struct EmptyAdaptRestrictProlong : public ALUGrid::Gitter :: AdaptRestrictProlong
64 {
preCoarseningEmptyAdaptRestrictProlong65   virtual int preCoarsening (HElemType & elem )   { return 1; }
postRefinementEmptyAdaptRestrictProlong66   virtual int postRefinement (HElemType & elem ) { return 1; }
preCoarseningEmptyAdaptRestrictProlong67   virtual int preCoarsening (HGhostType & bnd )     { return 1; }
postRefinementEmptyAdaptRestrictProlong68   virtual int postRefinement (HGhostType & bnd )    { return 1; }
69 };
70 
71 
72 // refine grid globally, i.e. mark all elements and then call adapt
73 template <class GitterType>
needConformingClosure(GitterType & grid,bool useClosure)74 bool needConformingClosure( GitterType& grid, bool useClosure )
75 {
76   bool needClosure = false ;
77   {
78     // get LeafIterator which iterates over all leaf elements of the grid
79     ALUGrid::LeafIterator < HElemType > w (grid) ;
80     w->first();
81     if( ! w->done() )
82     {
83       if( w->item ().type() == ALUGrid::tetra )
84       {
85         needClosure = useClosure ;
86       }
87     }
88   }
89   return needClosure ;
90 }
91 
92 // coarse grid globally, i.e. mark all elements for coarsening
93 // and then call adapt
94 template <class GitterType>
globalCoarsening(GitterType & grid,int refcount)95 void globalCoarsening(GitterType& grid, int refcount) {
96 
97   for (int count=refcount ; count > 0; count--)
98   {
99     std::cout << "Global Coarsening: run " << refcount-count << std::endl;
100     {
101        // get leafiterator which iterates over all leaf elements of the grid
102       ALUGrid::LeafIterator < HElemType > w (grid) ;
103 
104        for (w->first () ; ! w->done () ; w->next ())
105        {
106          // mark elements for coarsening
107          w->item ().tagForGlobalCoarsening() ;
108        }
109     }
110 
111     // create empty gather scatter
112     EmptyAdaptRestrictProlong rp;
113 
114     // adapt grid
115     grid.duneAdapt( rp );
116 
117     // print size of grid
118     grid.printsize () ;
119 
120   }
121 }
122 
123 
124 
125 // refine grid globally, i.e. mark all elements and then call adapt
126 template <class GitterType>
checkRefinements(GitterType & grid,int n)127 void checkRefinements( GitterType& grid, int n )
128 {
129   // if bisection is not enabled do nothing here
130   bool isHexa = false ;
131   {
132     // get LeafIterator which iterates over all leaf elements of the grid
133     ALUGrid::LeafIterator < HElemType > w (grid) ;
134     w->first();
135     if( ! w->done() )
136     {
137       if(  w->item ().type() != ALUGrid::tetra )
138       {
139         isHexa = true;
140       }
141     }
142   }
143 
144   if( isHexa )
145   {
146     typedef ALUGrid::Gitter ::Geometric :: HexaRule  HexaRule ;
147     const HexaRule rule = HexaRule::regular;
148 
149     {
150 
151       std::cout << "*********************************************" <<std::endl;
152       std::cout << "Refinement rule " << rule << std::endl;
153       std::cout << "*********************************************" <<std::endl;
154 
155       // get LeafIterator which iterates over all leaf elements of the grid
156       ALUGrid::LeafIterator < HElemType > w (grid) ;
157 
158       // create empty gather scatter
159       EmptyAdaptRestrictProlong rp;
160 
161       for(int j = 0; j<n ; ++j)
162       {
163 
164         for (w->first () ; ! w->done () ; w->next ())
165         {
166           if( w->item ().type() == ALUGrid::hexa )
167           {
168             typedef typename GitterType :: Objects :: hexa_IMPL hexa_IMPL ;
169             // mark element for refinement
170             hexa_IMPL* item = ((hexa_IMPL *) &w->item ());
171 
172             item->request ( rule );
173           }
174         }
175 
176         // adapt grid
177         grid.duneAdapt( rp );
178 
179         // print size of grid
180         grid.printsize () ;
181 
182       }
183 
184       // coarsen again
185       globalCoarsening( grid , n );
186     }
187   }
188   else // tetra
189   {
190     typedef ALUGrid::Gitter ::Geometric :: TetraRule  TetraRule ;
191     const TetraRule rules[ 2 ] =
192     { TetraRule::regular,
193      // TetraRule :: e01, TetraRule :: e12, TetraRule :: e20,
194      // TetraRule :: e23, TetraRule :: e30, TetraRule :: e31,
195      // TetraRule::iso4_2d,
196       TetraRule :: bisect
197     };
198 
199     for (int i=0; i<2; ++i )
200     {
201       std::cout << "*********************************************" <<std::endl;
202       std::cout << "Refinement rule " << rules[ i ] << std::endl;
203       std::cout << "*********************************************" <<std::endl;
204 
205       {
206         // get LeafIterator which iterates over all leaf elements of the grid
207         ALUGrid::LeafIterator < HElemType > w (grid) ;
208 
209         if (rules[ i ] == TetraRule::bisect ) grid.enableConformingClosure();
210 
211 
212       // create empty gather scatter
213       EmptyAdaptRestrictProlong rp;
214 
215       //initialize random seed
216       srand(time(NULL));
217 
218 
219       for(int j=0; j<n ; ++j){
220          int cnt =0;
221 
222       for (w->first () ; ! w->done () ; w->next ())
223         {
224         ++cnt;
225           if( w->item ().type() == ALUGrid::tetra )
226           {
227             typedef typename GitterType :: Objects :: tetra_IMPL tetra_IMPL ;
228             // mark element for refinement
229             tetra_IMPL* item = ((tetra_IMPL *) &w->item ());
230 
231            //if(rand() % 100 > 50){ //do some random refinement to simulate adaptive behavior
232 
233            if(cnt < 3){ //always refine the first  elements
234               item->request ( rules[ i ] );
235             }
236           }
237         }
238 
239 
240       // adapt grid
241       grid.duneAdapt( rp );
242 
243       // print size of grid
244       grid.printsize () ;
245        }
246       }
247 
248       // coarsen again - to be on the safe side because of conforming Closure take 2 times refinement steps
249       globalCoarsening( grid , 2*n );
250     } // end for
251   }
252 
253   std::cout << "*********************************************" <<std::endl;
254   std::cout << " Check of rules done " << std::endl;
255   std::cout << "*********************************************" <<std::endl;
256 }
257 
258 // exmaple on read grid, refine global and print again
main(int argc,char ** argv)259 int main (int argc, char ** argv)
260 {
261 #if HAVE_MPI
262   MPI_Init(&argc,&argv);
263 #endif
264   const bool printOutput = true ;
265 
266   int mxl = 0, glb = 0;
267   const char* filename = 0 ;
268   if (argc < 2)
269   {
270     filename = "../macrogrids/reference.tetra";
271     mxl = 1;
272     glb = 1;
273     std::cout << "usage: "<< argv[0] << " <macro grid> <opt: maxlevel> <opt: global refinement>\n";
274   }
275   else
276   {
277     filename = argv[ 1 ];
278   }
279 
280   const bool useClosure = argc > 4 ;
281 
282   {
283     int rank = 0;
284 #if HAVE_MPI
285     ALUGrid::MpAccessMPI mpa (MPI_COMM_WORLD);
286     rank = mpa.myrank();
287 #endif
288 
289     if (argc < 3)
290     {
291       if( rank == 0 )
292         std::cout << "Default level = "<< mxl << " choosen! \n";
293     }
294     else
295       mxl = atoi(argv[2]);
296     if (argc < 4)
297     {
298       if( rank == 0 )
299         std::cout << "Default global refinement = "<< glb << " choosen! \n";
300     }
301     else
302       glb = atoi(argv[3]);
303 
304     std::string macroname( filename );
305 
306     if( rank == 0 )
307     {
308       std::cout << "\n-----------------------------------------------\n";
309       std::cout << "read macro grid from < " << macroname << " > !" << std::endl;
310       std::cout << "-----------------------------------------------\n";
311     }
312 
313     const int dim = 2;
314     {
315 #if HAVE_MPI
316       ALUGrid::GitterDunePll* gridPtr = new ALUGrid::GitterDunePll(dim, macroname.c_str(),mpa);
317 #else
318       ALUGrid::GitterDuneImpl* gridPtr = new ALUGrid::GitterDuneImpl(dim, macroname.c_str());
319 #endif
320       bool closure = needConformingClosure( *gridPtr, useClosure );
321 #if HAVE_MPI
322       closure = mpa.gmax( closure );
323 #endif
324       if( closure )
325       {
326         gridPtr->enableConformingClosure() ;
327         gridPtr->disableGhostCells();
328       }
329 
330 
331       checkRefinements( *gridPtr , 3);
332     }
333   }
334 
335 #if HAVE_MPI
336   MPI_Finalize();
337 #endif
338   return 0;
339 }
340 
341