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