3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
gridadapt.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
23#ifndef DUMUX_GRIDADAPT_HH
24#define DUMUX_GRIDADAPT_HH
25
26#include <unordered_map>
27#include <dune/grid/common/partitionset.hh>
29
30#include "properties.hh"
32
33namespace Dumux
34{
35
46template<class TypeTag, bool adaptive>
48{
52
53 using Grid = typename GridView::Grid;
54 using LeafGridView = typename Grid::LeafGridView;
55 using Element = typename Grid::template Codim<0>::Entity;
56
59 using AdaptionInitializationIndicator = GetPropType<TypeTag, Properties::AdaptionInitializationIndicator>;
60
61 using IdSet = typename Grid::Traits::LocalIdSet;
62 using IdType = typename IdSet::IdType;
63
64public:
69 GridAdapt (Problem& problem)
70 : problem_(problem), adaptionIndicator_(problem), marked_(0), coarsened_(0)
71 {
72 levelMin_ = getParam<int>("GridAdapt.MinLevel");
73 levelMax_ = getParam<int>("GridAdapt.MaxLevel");
74 adaptationInterval_ = getParam<int>("GridAdapt.AdaptionInterval", 1);
75
76 if (levelMin_ < 0)
77 Dune::dgrave << __FILE__<< ":" <<__LINE__
78 << " : Dune cannot coarsen to gridlevels smaller 0! "<< std::endl;
79 }
80
88 void init()
89 {
90 adaptionIndicator_.init();
91
92 if (!getParam<bool>("GridAdapt.EnableInitializationIndicator"))
93 return;
94
95 AdaptionInitializationIndicator adaptionInitIndicator(problem_, adaptionIndicator_);
96
97 int maxIter = 2*levelMax_;
98 int iter = 0;
99 while (iter <= maxIter)
100 {
101 adaptGrid(adaptionInitIndicator);
102
103 if (!wasAdapted())
104 {
105 break;
106 }
107
108 int shouldInitialize = adaptionInitIndicator.initializeModel();
109 if (problem_.grid().comm().max(shouldInitialize))
110 problem_.model().initialize();
111
112 iter++;
113 }
114 }
115
131 {
132 adaptGrid(adaptionIndicator_) ;
133 }
134
151 template<class Indicator>
152 void adaptGrid(Indicator& indicator)
153 {
154 // reset internal counter for marked elements
155 marked_ = coarsened_ = 0;
156
157 // check for adaption interval: Adapt only at certain time step indices
158 if (problem_.timeManager().timeStepIndex() % adaptationInterval_ != 0)
159 return;
160
161 /**** 1) determine refining parameter if standard is used ***/
162 // if not, the indicatorVector and refinement Bounds have to
163 // specified by the problem through setIndicator()
164 indicator.calculateIndicator();
165
166 /**** 2) mark elements according to indicator *********/
167 markElements(indicator);
168
169 // abort if nothing in grid is marked
170 int sumMarked = problem_.grid().comm().sum(marked_);
171 int sumCoarsened = problem_.grid().comm().sum(coarsened_);
172 if (sumMarked == 0 && sumCoarsened == 0)
173 return;
174 else
175 Dune::dinfo << marked_ << " cells have been marked_ to be refined, "
176 << coarsened_ << " to be coarsened." << std::endl;
177
178 /**** 2b) Do pre-adaption step *****/
179 problem_.grid().preAdapt();
180 problem_.preAdapt();
181
182 /**** 3) Put primary variables in a map *********/
183 problem_.variables().storePrimVars(problem_);
184
185 /**** 4) Adapt Grid and size of variable vectors *****/
186 problem_.grid().adapt();
187
188 // forceRefineRatio(1);
189
190 // update mapper to new cell indices
191 using ElementMapper = std::decay_t<decltype(problem_.variables().elementMapper())>;
192 if constexpr (Deprecated::hasUpdateGridView<ElementMapper, GridView>())
193 problem_.variables().elementMapper().update(problem_.gridView());
194 else
195 Deprecated::update(problem_.variables().elementMapper());
196
197 // adapt size of vectors
198 problem_.variables().adaptVariableSize(problem_.variables().elementMapper().size());
199
200 /**** 5) (Re-)construct primary variables to new grid **/
201 problem_.variables().reconstructPrimVars(problem_);
202
203 // delete markers in grid
204 problem_.grid().postAdapt();
205
206 // call method in problem for potential output etc.
207 problem_.postAdapt();
208
209 return;
210 }
211
216 template<class Indicator>
217 void markElements(Indicator& indicator)
218 {
219 using CoarsenMarkerType = std::unordered_map<IdType, IdType>;
220 CoarsenMarkerType coarsenMarker;
221 const IdSet& idSet(problem_.grid().localIdSet());
222
223 for (const auto& element : elements(problem_.gridView()))
224 {
225 // only mark non-ghost elements
226 if (element.partitionType() == Dune::GhostEntity)
227 continue;
228
229 // refine?
230 if (indicator.refine(element) && element.level() < levelMax_)
231 {
232 problem_.grid().mark( 1, element);
233 ++marked_;
234
235 // this also refines the neighbor elements
236 checkNeighborsRefine_(element);
237 }
238 if (indicator.coarsen(element) && element.hasFather())
239 {
240 IdType idx = idSet.id(element.father());
241 auto it = coarsenMarker.find(idx);
242 if (it != coarsenMarker.end())
243 {
244 ++it->second;
245 }
246 else
247 {
248 coarsenMarker[idx] = 1;
249 }
250 }
251 }
252 // coarsen
253 for (const auto& element : elements(problem_.gridView()))
254 {
255 // only mark non-ghost elements
256 if (element.partitionType() == Dune::GhostEntity)
257 continue;
258
259 if (indicator.coarsen(element) && element.level() > levelMin_)
260 {
261 IdType idx = idSet.id(element.father());
262 auto it = coarsenMarker.find(idx);
263 if (it != coarsenMarker.end())
264 {
265 if (problem_.grid().getMark(element) == 0
266 && it->second == element.geometry().corners())
267 {
268 // check if coarsening is possible
269 bool coarsenPossible = true;
270 for(const auto& intersection : intersections(problem_.gridView(), element))
271 {
272 if(intersection.neighbor())
273 {
274 auto outside = intersection.outside();
275 if ((problem_.grid().getMark(outside) > 0)
276 || outside.level() > element.level())
277 {
278 coarsenPossible = false;
279 }
280 }
281 }
282
283 if(coarsenPossible)
284 {
285 problem_.grid().mark( -1, element );
286 ++coarsened_;
287 }
288 }
289 }
290 }
291 }
292 }
293
298 {
299 int sumMarked = problem_.grid().comm().sum(marked_);
300 int sumCoarsened = problem_.grid().comm().sum(coarsened_);
301
302 return (sumMarked != 0 || sumCoarsened != 0);
303 }
304
311 void setLevels(int levMin, int levMax)
312 {
313 if (levMin < 0)
314 Dune::dgrave << __FILE__<< ":" <<__LINE__
315 << " : Dune cannot coarsen to gridlevels smaller 0! "<< std::endl;
316 levelMin_ = levMin;
317 levelMax_ = levMax;
318 }
319
327 int getMaxLevel() const
328 {
329 return levelMax_;
330 }
338 int getMinLevel() const
339 {
340 return levelMin_;
341 }
342
343 AdaptionIndicator& adaptionIndicator()
344 {
345 return adaptionIndicator_;
346 }
347
348 AdaptionIndicator& adaptionIndicator() const
349 {
350 return adaptionIndicator_;
351 }
352
353private:
366 bool checkNeighborsRefine_(const Element &entity, int level = 1)
367 {
368 // this also refines the neighbor elements
369 for(const auto& intersection : intersections(problem_.gridView(), entity))
370 {
371 if(!intersection.neighbor())
372 continue;
373
374 auto outside = intersection.outside();
375
376 // only mark non-ghost elements
377 if (outside.partitionType() == Dune::GhostEntity)
378 continue;
379
380 if ((outside.level() < levelMax_)
381 && (outside.level() < entity.level()))
382 {
383 problem_.grid().mark(1, outside);
384 ++marked_;
385
386 if(level != levelMax_)
387 checkNeighborsRefine_(outside, ++level);
388 }
389 }
390 return true;
391 }
392
393
403 void forceRefineRatio(int maxLevelDelta = 1)
404 {
405 LeafGridView leafGridView = problem_.gridView();
406 // delete all existing marks
407 problem_.grid().postAdapt();
408 bool done;
409 do
410 {
411 // run through all cells
412 done=true;
413 for (const auto& element : elements(problem_.gridView()))
414 {
415 // only mark non-ghost elements
416 if (element.partitionType() == Dune::GhostEntity)
417 continue;
418
419 // run through all neighbor-cells (intersections)
420 for (const auto& intersection : intersections(leafGridView, element))
421 {
422 if(!intersection.neighbor())
423 continue;
424
425 if (element.level() + maxLevelDelta < intersection.outside().level())
426 {
427 problem_.grid().mark( 1, element );
428 done=false;
429 }
430 }
431 }
432 if (done==false)
433 {
434 // adapt the grid
435 problem_.grid().adapt();
436 // delete marks
437 problem_.grid().postAdapt();
438 }
439 }
440 while (done!=true);
441 }
442
443 // private Variables
444 Problem& problem_;
445 AdaptionIndicator adaptionIndicator_;
446
447 int marked_;
448 int coarsened_;
449
450 int levelMin_;
451 int levelMax_;
452
453 int adaptationInterval_;
454};
455
463template<class TypeTag>
464class GridAdapt<TypeTag, false>
465{
469 using ScalarSolutionType = typename SolutionTypes::ScalarSolution;
470
471public:
472 void init()
473 {}
475 {}
477 {
478 return false;
479 }
480 void setLevels(int, int)
481 {}
482 void setTolerance(int, int)
483 {}
484 void setIndicator(const ScalarSolutionType&,
485 const Scalar&, const Scalar&)
486 {}
487 GridAdapt (Problem& problem)
488 {}
489};
490
491}
492#endif
Helpers for deprecation.
Defines a type tag and some fundamental properties for linear solvers.
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property
Definition: propertysystem.hh:141
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
Standard Module for h-adaptive simulations.
Definition: gridadapt.hh:48
void adaptGrid(Indicator &indicator)
Method to adapt the grid with individual indicator vector.
Definition: gridadapt.hh:152
GridAdapt(Problem &problem)
Definition: gridadapt.hh:69
int getMaxLevel() const
Returns maximum refinement level.
Definition: gridadapt.hh:327
AdaptionIndicator & adaptionIndicator()
Definition: gridadapt.hh:343
AdaptionIndicator & adaptionIndicator() const
Definition: gridadapt.hh:348
void adaptGrid()
Standard method to adapt the grid.
Definition: gridadapt.hh:130
void setLevels(int levMin, int levMax)
Definition: gridadapt.hh:311
bool wasAdapted()
Returns true if grid cells have been marked for adaptation.
Definition: gridadapt.hh:297
void markElements(Indicator &indicator)
Definition: gridadapt.hh:217
void init()
Initalization method of the h-adaptive module.
Definition: gridadapt.hh:88
int getMinLevel() const
Returns minimum refinement level.
Definition: gridadapt.hh:338
GridAdapt(Problem &problem)
Definition: gridadapt.hh:487
void adaptGrid()
Definition: gridadapt.hh:474
void setLevels(int, int)
Definition: gridadapt.hh:480
void setIndicator(const ScalarSolutionType &, const Scalar &, const Scalar &)
Definition: gridadapt.hh:484
void init()
Definition: gridadapt.hh:472
bool wasAdapted()
Definition: gridadapt.hh:476
void setTolerance(int, int)
Definition: gridadapt.hh:482
Base file for properties related to sequential models.