19#ifndef DUMUX_GRIDADAPTINITIALIZATIONINDICATOR_HH
20#define DUMUX_GRIDADAPTINITIALIZATIONINDICATOR_HH
24#include <dune/common/dynvector.hh>
39template<
class TypeTag>
40class GridAdaptInitializationIndicator
43 using Problem = GetPropType<TypeTag, Properties::Problem>;
44 using GridView =
typename GetPropType<TypeTag, Properties::GridGeometry>::GridView;
45 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
46 using Element =
typename GridView::Traits::template Codim<0>::Entity;
47 using Intersection =
typename GridView::Intersection;
49 using AdaptionIndicator = GetPropType<TypeTag, Properties::AdaptionIndicator>;
51 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
52 using BoundaryTypes = GetPropType<TypeTag, Properties::BoundaryTypes>;
56 dim = GridView::dimension,
57 dimWorld = GridView::dimensionworld,
58 numEq = getPropValue<TypeTag, Properties::NumEq>(),
59 numPhases = getPropValue<TypeTag, Properties::NumPhases>()
68 using LocalPosition = Dune::FieldVector<Scalar, dim>;
69 using LocalPositionFace = Dune::FieldVector<Scalar, dim-1>;
70 using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>;
72 void virtualHierarchicSourceSearch_(PrimaryVariables &source,
const Element& element)
74 int level = element.level();
76 if (level == maxAllowedLevel_)
78 GlobalPosition globalPos = element.geometry().center();
79 problem_.sourceAtPos(source, globalPos);
84 unsigned int numRefine = maxAllowedLevel_ - level;
85 int numCheckCoords = pow(2, numRefine);
87 LocalPosition localPos(0.0);
88 GlobalPosition globalPosCheck(0.0);
89 Scalar halfInterval = (1.0/double(numCheckCoords))/2.;
91 PrimaryVariables sourceCheck(0.0);
94 for (
int i = 1; i <= numCheckCoords; i++)
96 for (
int j = 1; j <= numCheckCoords; j++)
98 localPos[0] = double(i)/double(numCheckCoords) - halfInterval;
99 localPos[1] = double(j)/double(numCheckCoords) - halfInterval;
102 globalPosCheck = element.geometry().global(localPos);
103 problem_.sourceAtPos(sourceCheck, globalPosCheck);
105 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
107 if (abs(sourceCheck[eqIdx]) > abs(source[eqIdx]))
109 source[eqIdx] = sourceCheck[eqIdx];
115 for (
int k = 1; k <= numCheckCoords; k++)
117 localPos[2] = double(k)/double(numCheckCoords) - halfInterval;
118 globalPosCheck = element.geometry().global(localPos);
119 problem_.sourceAtPos(sourceCheck, globalPosCheck);
121 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
123 if (abs(sourceCheck[eqIdx]) > abs(source[eqIdx]))
125 source[eqIdx] = sourceCheck[eqIdx];
134 void virtualHierarchicBCSearch_(BoundaryTypes &bcTypes, PrimaryVariables &values,
const Element& element,
const Intersection& intersection)
136 int level = element.level();
138 if (level == maxAllowedLevel_)
140 GlobalPosition globalPos = intersection.geometry().center();
141 problem_.boundaryTypesAtPos(bcTypes, globalPos);
145 for (
int i = 0; i < numEq; i++)
147 if (bcTypes.isNeumann(i))
149 PrimaryVariables fluxes;
150 problem_.neumannAtPos(fluxes, globalPos);
159 unsigned int numRefine = maxAllowedLevel_ - level;
160 int numCheckCoords = pow(2, numRefine);
162 LocalPositionFace localPos(0.0);
163 GlobalPosition globalPosCheck(0.0);
164 Scalar halfInterval = (1.0/double(numCheckCoords))/2.;
166 PrimaryVariables fluxCheck(0.0);
168 for (
int i = 1; i <= numCheckCoords; i++)
170 localPos[0] = double(i)/double(numCheckCoords) - halfInterval;
173 globalPosCheck = intersection.geometry().global(localPos);
174 problem_.boundaryTypesAtPos(bcTypes, globalPosCheck);
176 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
178 if (refineAtDirichletBC_ && bcTypes.isDirichlet(eqIdx))
182 else if (refineAtFluxBC_ && bcTypes.isNeumann(eqIdx))
184 problem_.neumannAtPos(fluxCheck, globalPosCheck);
192 for (
int k = 1; k <= numCheckCoords; k++)
194 localPos[1] = double(k)/double(numCheckCoords) - halfInterval;
195 globalPosCheck = intersection.geometry().global(localPos);
197 problem_.boundaryTypesAtPos(bcTypes, globalPosCheck);
200 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
202 if (refineAtDirichletBC_ && bcTypes.isDirichlet(eqIdx))
206 else if (refineAtFluxBC_ && bcTypes.isNeumann(eqIdx))
208 problem_.neumannAtPos(fluxCheck, globalPosCheck);
227 if (nextMaxLevel_ == maxAllowedLevel_)
228 adaptionIndicator_.calculateIndicator();
231 indicatorVector_.resize(problem_.variables().cellDataGlobal().size());
233 indicatorVector_ = coarsenCell;
235 if (!enableInitializationIndicator_)
243 for (
const auto& element : elements(problem_.gridView()))
245 int globalIdxI = problem_.variables().index(element);
247 int level = element.level();
248 maxLevel_ = max(level, maxLevel_);
250 if (level < minAllowedLevel_)
252 nextMaxLevel_ = min(max(level + 1, nextMaxLevel_), maxAllowedLevel_);
253 indicatorVector_[globalIdxI] = refineCell;
259 PrimaryVariables source(0.0);
260 virtualHierarchicSourceSearch_(source, element);
261 for (
int i = 0; i < numEq; i++)
263 if (abs(source[i]) > 1e-10)
265 nextMaxLevel_ = min(max(level + 1, nextMaxLevel_), maxAllowedLevel_);
266 indicatorVector_[globalIdxI] = refineCell;
272 if (indicatorVector_[globalIdxI] != refineCell && (refineAtDirichletBC_ || refineAtFluxBC_))
275 for (
const auto& intersection : intersections(problem_.gridView(), element))
277 if (intersection.boundary() && indicatorVector_[globalIdxI] != refineCell)
279 BoundaryTypes bcTypes;
280 PrimaryVariables values(0.0);
282 virtualHierarchicBCSearch_(bcTypes, values, element, intersection);
285 for (
int i = 0; i < numEq; i++)
287 if (bcTypes.isDirichlet(i) && refineAtDirichletBC_)
289 nextMaxLevel_ = min(max(level + 1, nextMaxLevel_), maxAllowedLevel_);
290 indicatorVector_[globalIdxI] = refineCell;
294 for (
int j = 0; j < numPhases; j++)
296 if (abs(values[j]) > 1e-10)
298 nextMaxLevel_ = min(max(level + 1, nextMaxLevel_), maxAllowedLevel_);
299 indicatorVector_[globalIdxI] = refineCell;
318 int idx = problem_.elementMapper().index(element);
320 if (indicatorVector_[idx] == refineCell)
322 else if (maxLevel_ == maxAllowedLevel_)
323 return adaptionIndicator_.refine(element);
336 int idx = problem_.elementMapper().index(element);
338 if (indicatorVector_[idx] == coarsenCell && maxLevel_ < maxAllowedLevel_)
340 else if (indicatorVector_[idx] == coarsenCell && !adaptionIndicator_.refine(element))
357 return nextMaxLevel_ == maxAllowedLevel_;
371 problem_(problem), adaptionIndicator_(adaptionIndicator), maxLevel_(0), nextMaxLevel_(0)
373 minAllowedLevel_ = getParam<int>(
"GridAdapt.MinLevel");
374 maxAllowedLevel_ = getParam<int>(
"GridAdapt.MaxLevel");
375 enableInitializationIndicator_ = getParam<bool>(
"GridAdapt.EnableInitializationIndicator");
376 refineAtDirichletBC_ = getParam<bool>(
"GridAdapt.RefineAtDirichletBC");
377 refineAtFluxBC_ = getParam<bool>(
"GridAdapt.RefineAtFluxBC");
378 refineAtSource_ = getParam<bool>(
"GridAdapt.RefineAtSource");
380 if (!refineAtDirichletBC_ && !refineAtFluxBC_ && !refineAtSource_)
382 nextMaxLevel_ = maxAllowedLevel_;
383 maxLevel_ = maxAllowedLevel_;
389 AdaptionIndicator& adaptionIndicator_;
390 Dune::DynamicVector<int> indicatorVector_;
393 int minAllowedLevel_;
394 int maxAllowedLevel_;
395 bool enableInitializationIndicator_;
396 bool refineAtDirichletBC_;
397 bool refineAtFluxBC_;
398 bool refineAtSource_;
void calculateIndicator()
Calculates the indicator used for refinement/coarsening for each grid cell.
Definition: gridadaptinitializationindicator.hh:224
bool initializeModel()
Definition: gridadaptinitializationindicator.hh:355
void init()
Initializes the adaption indicator class.
Definition: gridadaptinitializationindicator.hh:352
bool refine(const Element &element)
Indicator function for marking of grid cells for refinement.
Definition: gridadaptinitializationindicator.hh:316
int maxLevel()
Definition: gridadaptinitializationindicator.hh:346
GridAdaptInitializationIndicator(Problem &problem, AdaptionIndicator &adaptionIndicator)
Constructs a GridAdaptionIndicator instance.
Definition: gridadaptinitializationindicator.hh:370
bool coarsen(const Element &element)
Indicator function for marking of grid cells for coarsening.
Definition: gridadaptinitializationindicator.hh:334
Base file for properties related to sequential models.