diff --git a/examples/2pinfiltration/main.cc b/examples/2pinfiltration/main.cc index 77143802c0a1787b4bcb81d2b52babfdcec3ee66..41db9c2cb599a2995180989e66f8e364bb166b11 100644 --- a/examples/2pinfiltration/main.cc +++ b/examples/2pinfiltration/main.cc @@ -129,24 +129,15 @@ int main(int argc, char** argv) try TwoPGridDataTransfer<TypeTag> dataTransfer(problem, gridGeometry, gridVariables, x); // [[/codeblock]] - // We do an initial refinement around sources/BCs. We use the `GridAdaptInitializationIndicator` defined in `dumux/adaptive/initializationindicator.hh` for that. - GridAdaptInitializationIndicator<TypeTag> initIndicator(problem, gridGeometry, gridVariables); - - // We refine up to the maximum level. For every level, the indicator used for the refinement/coarsening is calculated. - // If any grid cells have to be adapted, the gridvariables and the pointsourcemap are updated. - // [[codeblock]] - const auto maxLevel = getParam<std::size_t>("Adaptive.MaxLevel", 0); - for (std::size_t i = 0; i < maxLevel; ++i) - { - // we calculate the initial indicator for adaption for each grid cell using the initial solution x - initIndicator.calculate(x); - - // and then we mark the elements that were adapted. + // Convenience functions to perform a grid adaptation given a pre-calculated indicator. + // [[codeblock]] + const auto adaptGridAndVariables = [&] (auto& indicator) { + // We mark and adapt the elements according to the indicator. bool wasAdapted = false; - if (markElements(gridManager.grid(), initIndicator)) + if (markElements(gridManager.grid(), indicator)) wasAdapted = adapt(gridManager.grid(), dataTransfer); - // In case of any marked elements, the gridvariables and the pointsourcemap are updated. + // In case of any adapted elements, the gridvariables and the pointsourcemap are updated. if (wasAdapted) { // We overwrite the old solution with the new (resized & interpolated) one @@ -156,30 +147,21 @@ int main(int argc, char** argv) try // we update the point source map after adaption problem->computePointSourceMap(); } - } + }; // [[/codeblock]] - // Depending on the initial conditions, another grid adaptation might be necessary. - // The gridadaptindicator uses the input parameters `Adaptive.RefineTolerance` and `Adaptive.CoarsenTolerance` for this step. - // Again, if elements were adapted, we mark them and update gridvariables and the pointsourcemap accordingly. - // [[codeblock]] - indicator.calculate(x, refineTol, coarsenTol); - - // we mark the elements that were adapted - bool wasAdapted = false; - if (markElements(gridManager.grid(), indicator)) - wasAdapted = adapt(gridManager.grid(), dataTransfer); - - // In case of an additional grid adaptation, the gridvariables and the pointsourcemap are updated again. - if (wasAdapted) + // We do initial refinements around sources/BCs, for which we use the `GridAdaptInitializationIndicator` defined in `dumux/adaptive/initializationindicator.hh`. + // Afterwards, depending on the initial conditions, another grid adaptation using our `indicator` above might be necessary, which uses + // `Adaptive.RefineTolerance` and `Adaptive.CoarsenTolerance` for this step. + GridAdaptInitializationIndicator<TypeTag> initIndicator(problem, gridGeometry, gridVariables); + const auto maxLevel = getParam<std::size_t>("Adaptive.MaxLevel", 0); + for (std::size_t i = 0; i < maxLevel; ++i) { - // Overwrite the old solution with the new (resized & interpolated) one - xOld = x; - // Initialize the secondary variables to the new (and "new old") solution - gridVariables->updateAfterGridAdaption(x); - // Update the point source map - problem->computePointSourceMap(); + initIndicator.calculate(x); + adaptGridAndVariables(initIndicator); } + indicator.calculate(x, refineTol, coarsenTol); + adaptGridAndVariables(indicator); // [[/codeblock]] // #### Solving the problem @@ -221,30 +203,13 @@ int main(int argc, char** argv) try { // We only want to refine/coarsen after first time step is finished, not before. // The initial refinement was already done before the start of the time loop. - // This means we only refine when the time is greater than 0. + // This means we only refine when the time is greater than 0. Note that we now also + // have to update the assembler, since the sizes of the residual vector and jacobian matrix change. if (timeLoop->time() > 0) { - // again we compute the refinement indicator with the `TwoPGridAdaptIndicator` indicator.calculate(x, refineTol, coarsenTol); - - // we mark elements and adapt grid if necessary - wasAdapted = false; - if (markElements(gridManager.grid(), indicator)) - wasAdapted = adapt(gridManager.grid(), dataTransfer); - - // In case of a grid adaptation, the gridvariables and the pointsourcemap are updated again. - if (wasAdapted) - { - // We overwrite the old solution with the new (resized & interpolated) one - xOld = x; - // We initialize the secondary variables to the new (and "new old") solution - gridVariables->updateAfterGridAdaption(x); - // We also need to update the assembler (sizes of residual and Jacobian change) - assembler->updateAfterGridAdaption(); - // We update the point source map - problem->computePointSourceMap(); - } - // we leave the refinement step + adaptGridAndVariables(indicator); + assembler->updateAfterGridAdaption(); } // We solve the non-linear system with time step control.