diff --git a/dumux/implicit/common/adaptationhelper.hh b/dumux/implicit/common/adaptationhelper.hh new file mode 100644 index 0000000000000000000000000000000000000000..8d692692bf2c4b5edc0402690459271a269f986c --- /dev/null +++ b/dumux/implicit/common/adaptationhelper.hh @@ -0,0 +1,288 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +#ifndef DUMUX_ADAPTATIONHELPER_HH +#define DUMUX_ADAPTATIONHELPER_HH + +#include <dune/grid/utility/persistentcontainer.hh> +//#include <dumux/linear/vectorexchange.hh> + +/** + * @file + * @brief Base class holding the variables for implicit models. + */ + +namespace Dumux +{ + +template<class TypeTag> +class AdaptationHelper +{ +private: + typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; + typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; + + struct AdaptedValues + { + PrimaryVariables u; + int count; + AdaptedValues() + { + count = 0; + } + }; + + typedef typename GridView::Grid Grid; + typedef typename Grid::LevelGridView LevelGridView; + typedef typename LevelGridView::template Codim<0>::Iterator LevelIterator; + typedef typename GridView::Traits::template Codim<0>::EntityPointer ElementPointer; + typedef typename GridView::Traits::template Codim<0>::Entity Element; + typedef Dune::PersistentContainer<Grid, AdaptedValues> PersistentContainer; + +private: + const GridView gridView_; + const Grid& grid_; + PersistentContainer adaptationMap_; + +public: + //! Constructs an adaptive helper object + /** + * In addition to providing a storage object for cell-centered Methods, this class provides + * mapping functionality to adapt the grid. + * + * @param gridView a DUNE gridview object corresponding to diffusion and transport equation + */ + AdaptationHelper(const GridView& gridView) : + gridView_(gridView), grid_(gridView.grid()), adaptationMap_(grid_, 0) + {} + + + /*! + * Store primary variables + * + * To reconstruct the solution in father elements, problem properties might + * need to be accessed. + * From upper level on downwards, the old solution is stored into an container + * object, before the grid is adapted. Father elements hold averaged information + * from the son cells for the case of the sons being coarsened. + * + * @param problem The current problem + */ + void storePrimVars(Problem& problem) + { + adaptationMap_.resize(); + + // loop over all levels of the grid + for (int level = grid_.maxLevel(); level >= 0; level--) + { + //get grid view on level grid + LevelGridView levelView = grid_.levelGridView(level); + + for (LevelIterator eIt = levelView.template begin<0>(); eIt != levelView.template end<0>(); ++eIt) + { + //get your map entry + AdaptedValues &adaptedValues = adaptationMap_[*eIt]; + + // put your value in the map + if (eIt->isLeaf()) + { + // get index + int indexI = this->elementIndex(*eIt, problem); + + storeAdaptionValues(adaptedValues, problem.model().curSol()[indexI]); + + adaptedValues.count = 1; + } + //Average in father + if (eIt->level() > 0) + { + ElementPointer epFather = eIt->father(); + int indexI = this->elementIndex(*epFather, problem); + AdaptedValues& adaptedValuesFather = adaptationMap_[*epFather]; + adaptedValuesFather.count += 1; + storeAdaptionValues(adaptedValues, adaptedValuesFather, + problem.model().curSol()[indexI]); + } + } + } + } + + /*! + * Reconstruct missing primary variables (where elements are created/deleted) + * + * To reconstruct the solution in father elements, problem properties might + * need to be accessed. + * Starting from the lowest level, the old solution is mapped on the new grid: + * Where coarsened, new cells get information from old father element. + * Where refined, a new solution is reconstructed from the old father cell, + * and then a new son is created. That is then stored into the general data + * structure (CellData). + * + * @param problem The current problem + */ + void reconstructPrimVars(Problem& problem) + { + adaptationMap_.resize(); + + for (int level = 0; level <= grid_.maxLevel(); level++) + { + LevelGridView levelView = grid_.levelGridView(level); + + for (LevelIterator eIt = levelView.template begin<0>(); eIt != levelView.template end<0>(); ++eIt) + { + // only treat non-ghosts, ghost data is communicated afterwards + if (eIt->partitionType() == Dune::GhostEntity) + continue; + + if (!eIt->isNew()) + { + //entry is in map, write in leaf + if (eIt->isLeaf()) + { + AdaptedValues &adaptedValues = adaptationMap_[*eIt]; + int newIdxI = this->elementIndex(*eIt, problem); + + setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]); + } + } + else + { + // value is not in map, interpolate from father element + if (eIt->level() > 0) + { + ElementPointer epFather = eIt->father(); + + // create new entry: reconstruct from adaptationMap_[*father] to a new + // adaptationMap_[*son] + reconstructAdaptionValues(adaptationMap_, *epFather, *eIt, problem); + + // access new son + AdaptedValues& adaptedValues = adaptationMap_[*eIt]; + adaptedValues.count = 1; + + // if we are on leaf, store reconstructed values of son in CellData object + if (eIt->isLeaf()) + { + // acess new CellData object + int newIdxI = this->elementIndex(*eIt, problem); + + setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]); + } + } + } + } + + } + // reset entries in restrictionmap + adaptationMap_.resize( typename PersistentContainer::Value() ); + adaptationMap_.shrinkToFit(); + adaptationMap_.fill( typename PersistentContainer::Value() ); + +//#if HAVE_MPI +// // communicate ghost data +// typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes; +// typedef typename SolutionTypes::ElementMapper ElementMapper; +// typedef VectorExchange<ElementMapper, std::vector<CellData> > DataHandle; +// DataHandle dataHandle(problem.elementMapper(), this->cellDataGlobal()); +// problem.gridView().template communicate<DataHandle>(dataHandle, +// Dune::InteriorBorder_All_Interface, +// Dune::ForwardCommunication); +//#endif + } + + //! Stores values to be adapted in an adaptedValues container + /** + * Stores values to be adapted from the current CellData objects into + * the adaptation container in order to be mapped on a new grid. + * + * \param adaptedValues Container for model-specific values to be adapted + * \param element The element to be stored + */ + static void storeAdaptionValues(AdaptedValues& adaptedValues, const PrimaryVariables& u) + { + adaptedValues.u = u; + } + //! Stores sons entries into father element for averaging + /** + * Sum up the adaptedValues (sons values) into father element. We store from leaf + * upwards, so sons are stored first, then cells on the next leaf (=fathers) + * can be averaged. + * + * \param adaptedValues Container for model-specific values to be adapted + * \param adaptedValuesFather Values to be adapted of father cell + * \param fatherElement The element of the father + */ + static void storeAdaptionValues(AdaptedValues& adaptedValues, + AdaptedValues& adaptedValuesFather, + const PrimaryVariables& u) + { + adaptedValuesFather.u += adaptedValues.u; + adaptedValuesFather.u /= adaptedValues.count; + } + //! Set adapted values in CellData + /** + * This methods stores reconstructed values into the cellData object, by + * this setting a newly mapped solution to the storage container of the + * decoupled models. + * + * \param adaptedValues Container for model-specific values to be adapted + * \param element The element where things are stored. + */ + static void setAdaptionValues(AdaptedValues& adaptedValues, PrimaryVariables& u) + { + PrimaryVariables uNew = adaptedValues.u; + uNew /= adaptedValues.count; + + u = uNew; + } + + //! Reconstructs sons entries from data of father cell + /** + * Reconstructs a new solution from a father cell into a newly + * generated son cell. New cell is stored into the global + * adaptationMap. + * + * \param adaptionMap Global map storing all values to be adapted + * \param father Entity Pointer to the father cell + * \param son Entity Pointer to the newly created son cell + * \param problem The problem + */ + static void reconstructAdaptionValues(Dune::PersistentContainer<Grid, AdaptedValues>& adaptionMap, + const Element& father, const Element& son, const Problem& problem) + { + AdaptedValues& adaptedValues = adaptionMap[son]; + AdaptedValues& adaptedValuesFather = adaptionMap[father]; + + adaptedValues.u = adaptedValuesFather.u; + adaptedValues.u /= adaptedValuesFather.count; + + } + + int elementIndex(const Element& element, const Problem& problem) const + { +#if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4) + return problem.elementMapper().index(element); +#else + return problem.elementMapper().map(element); +#endif + } + +}; +} +#endif diff --git a/dumux/implicit/common/gridadapt.hh b/dumux/implicit/common/gridadapt.hh new file mode 100644 index 0000000000000000000000000000000000000000..5d111cd6453ce488fdb71e5efce8bace2bbf4bce --- /dev/null +++ b/dumux/implicit/common/gridadapt.hh @@ -0,0 +1,495 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief Base class for h-adaptive sequential models. + */ +#ifndef DUMUX_IMPLICIT_GRIDADAPT_HH +#define DUMUX_IMPLICIT_GRIDADAPT_HH + +#include "gridadaptproperties.hh" +#include "adaptationhelper.hh" +#include <unordered_map> + +namespace Dumux +{ + +/*!\ingroup IMPET + * @brief Standard Module for h-adaptive simulations + * + * This class is created by the problem class with the template + * parameters <TypeTag, true> and provides basic functionality + * for adaptive methods: + * + * A standard implementation adaptGrid() will prepare everything + * to calculate the next pressure field on the new grid. + */ +template<class TypeTag, bool adaptive> +class ImplicitGridAdapt +{ + typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; + typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + + typedef typename GridView::Grid Grid; + typedef typename Grid::LeafGridView LeafGridView; + typedef typename LeafGridView::template Codim<0>::Iterator LeafIterator; + typedef typename GridView::IntersectionIterator LeafIntersectionIterator; + typedef typename Grid::template Codim<0>::Entity Element; + typedef typename Grid::template Codim<0>::EntityPointer ElementPointer; + + typedef typename GET_PROP_TYPE(TypeTag, AdaptionIndicator) AdaptionIndicator; + typedef typename GET_PROP_TYPE(TypeTag, AdaptionInitializationIndicator) AdaptionInitializationIndicator; + +public: + /*! + * Constructor for h-adaptive simulations (adaptive grids) + * @param problem The problem + */ + ImplicitGridAdapt (Problem& problem) + : problem_(problem), adaptationHelper_(problem.gridView()), adaptionIndicator_(problem), marked_(0), coarsened_(0) + { + levelMin_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, MinLevel); + levelMax_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, MaxLevel); + adaptationInterval_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, AdaptionInterval); + + if (levelMin_ < 0) + Dune::dgrave << __FILE__<< ":" <<__LINE__ + << " : Dune cannot coarsen to gridlevels smaller 0! "<< std::endl; + } + + /*! + * @brief Initalization method of the h-adaptive module + * + * Prepares the grid for simulation after the initialization of the + * problem. The applied indicator is selectable via the property + * AdaptionInitializationIndicator + */ + void init() + { + adaptionIndicator_.init(); + + if (!GET_PARAM_FROM_GROUP(TypeTag, bool, GridAdapt, EnableInitializationIndicator)) + return; + + AdaptionInitializationIndicator adaptionInitIndicator(problem_, adaptionIndicator_); + + int maxIter = 2*levelMax_; + int iter = 0; + while (iter <= maxIter) + { + adaptGrid(adaptionInitIndicator); + + if (!wasAdapted()) + { + break; + } + + int shouldInitialize = adaptionInitIndicator.initializeModel(); + if (problem_.grid().comm().max(shouldInitialize)) + problem_.model().init(problem_); + + iter++; + } + } + + /*! + * @brief Standard method to adapt the grid + * + * This method is called from IMPETProblem::preTimeStep() if + * adaptive grids are used in the simulation. It uses the standard + * indicator (selected by the property AdaptionIndicator) and forwards to + * with it to the ultimate method adaptGrid(indicator), which + * uses a standard procedure for adaptivity: + * 1) Determine the refinement indicator + * 2) Mark the elements + * 3) Store primary variables in a map + * 4) Adapt the grid, adapt variables sizes, update mappers + * 5) Reconstruct primary variables, regain secondary variables + */ + void adaptGrid() + { + adaptGrid(adaptionIndicator_) ; + } + + /*! + * @brief Method to adapt the grid with individual indicator vector + * + * @param indicator The refinement indicator that is applied + * + * This method is called by an user-defined preTimeStep() of + * the applied problem and takes a given vector with indicator + * values. + * + * It uses a standard procedure for adaptivity: + * 1) Determine the refinement indicator + * 2) Mark the elements + * 3) Store primary variables in a map + * 4) Adapt the grid, adapt variables sizes, update mappers + * 5) Reconstruct primary variables, regain secondary variables + */ + template<class Indicator> + void adaptGrid(Indicator& indicator) + { + // reset internal counter for marked elements + marked_ = coarsened_ = 0; + + // check for adaption interval: Adapt only at certain time step indices + if (problem_.timeManager().timeStepIndex() % adaptationInterval_ != 0) + return; + + /**** 1) determine refining parameter if standard is used ***/ + // if not, the indicatorVector and refinement Bounds have to + // specified by the problem through setIndicator() + indicator.calculateIndicator(); + + /**** 2) mark elements according to indicator *********/ + markElements(indicator); + + // abort if nothing in grid is marked + int sumMarked = problem_.grid().comm().sum(marked_); + int sumCoarsened = problem_.grid().comm().sum(coarsened_); + if (sumMarked == 0 && sumCoarsened == 0) + return; + else + Dune::dinfo << marked_ << " cells have been marked_ to be refined, " + << coarsened_ << " to be coarsened." << std::endl; + + /**** 2b) Do pre-adaption step *****/ + problem_.grid().preAdapt(); + problem_.preAdapt(); + + /**** 3) Put primary variables in a map *********/ + adaptationHelper_.storePrimVars(problem_); + + /**** 4) Adapt Grid and size of variable vectors *****/ + problem_.grid().adapt(); + + // forceRefineRatio(1); + + // update mapper to new cell indices + problem_.elementMapper().update(); + + // adapt size of vectors + problem_.model().adaptVariableSize(); + + /**** 5) (Re-)construct primary variables to new grid **/ + adaptationHelper_.reconstructPrimVars(problem_); + + // delete markers in grid + problem_.grid().postAdapt(); + + // call method in problem for potential output etc. + problem_.postAdapt(); + + return; + } + + /*! + * Mark Elements for grid refinement according to applied Indicator + * @return Total ammount of marked cells + */ + template<class Indicator> + void markElements(Indicator& indicator) + { + typedef std::unordered_map<int, int> CoarsenMarkerType; + CoarsenMarkerType coarsenMarker; + const typename Grid::Traits::LocalIdSet& idSet(problem_.grid().localIdSet()); + + for (LeafIterator eIt = problem_.gridView().template begin<0>(); + eIt!=problem_.gridView().template end<0>(); ++eIt) + { + // only mark non-ghost elements + if (eIt->partitionType() == Dune::GhostEntity) + continue; + + // refine? + if (indicator.refine(*eIt) && eIt->level() < levelMax_) + { + problem_.grid().mark( 1, *eIt); + ++marked_; + + // this also refines the neighbor elements + checkNeighborsRefine_(*eIt); + } + if (indicator.coarsen(*eIt) && eIt->hasFather()) + { + int idx = idSet.id(*(eIt->father())); + typename CoarsenMarkerType::iterator it = coarsenMarker.find(idx); + if (it != coarsenMarker.end()) + { + it->second++; + } + else + { + coarsenMarker[idx] = 1; + } + } + } + // coarsen + for (LeafIterator eIt = problem_.gridView().template begin<0>(); + eIt!=problem_.gridView().template end<0>(); ++eIt) + { + // only mark non-ghost elements + if (eIt->partitionType() == Dune::GhostEntity) + continue; + + if (indicator.coarsen(*eIt) && eIt->level() > levelMin_) + { + int idx = idSet.id(*(eIt->father())); + typename CoarsenMarkerType::iterator it = coarsenMarker.find(idx); + if (it != coarsenMarker.end()) + { + if (problem_.grid().getMark(*eIt) == 0 + && it->second == eIt->geometry().corners()) + { + // check if coarsening is possible + bool coarsenPossible = true; + LeafIntersectionIterator isend = problem_.gridView().iend(*eIt); + for(LeafIntersectionIterator is = problem_.gridView().ibegin(*eIt); is != isend; ++is) + { + if(is->neighbor()) + { + ElementPointer outside = is->outside(); + if ((problem_.grid().getMark(*outside) > 0) + || outside->level() > eIt->level()) + { + coarsenPossible = false; + } + } + } + + if(coarsenPossible) + { + problem_.grid().mark( -1, *eIt ); + ++coarsened_; + } + } + } + } + } + } + + /*! + * @brief Returns true if grid cells have been marked for adaptation + */ + bool wasAdapted() + { + int sumMarked = problem_.grid().comm().sum(marked_); + int sumCoarsened = problem_.grid().comm().sum(coarsened_); + + return (sumMarked != 0 || sumCoarsened != 0); + } + + /*! + * Sets minimum and maximum refinement levels + * + * @param levMin minimum level for coarsening + * @param levMax maximum level for refinement + */ + void setLevels(int levMin, int levMax) + { + if (levMin < 0) + Dune::dgrave << __FILE__<< ":" <<__LINE__ + << " : Dune cannot coarsen to gridlevels smaller 0! "<< std::endl; + levelMin_ = levMin; + levelMax_ = levMax; + } + + /*! + * @brief Returns maximum refinement level + * + * The value is the assign maximum possible level, + * not the actual maximum level of the grid. + * @return levelMax_ maximum level for refinement + */ + const int getMaxLevel() const + { + return levelMax_; + } + /*! + * @brief Returns minimum refinement level + * + * The value is the assign minimum possible level, + * not the actual minimum level of the grid. + * @return levelMin_ minimum level for coarsening + */ + const int getMinLevel() const + { + return levelMin_; + } + + AdaptionIndicator& adaptionIndicator() + { + return adaptionIndicator_; + } + + AdaptionIndicator& adaptionIndicator() const + { + return adaptionIndicator_; + } + +private: + AdaptationHelper<TypeTag> adaptationHelper_; + + + /*! + * @brief Method ensuring the refinement ratio of 2:1 + * + * For any given entity, a loop over the neighbors checks weather the + * entities refinement would require that any of the neighbors has + * to be refined, too. + * This is done recursively over all levels of the grid. + * + * @param entity Element of interest that is to be refined + * @param level level of the refined entity: it is at least 1 + * @return true if everything was successful + */ + bool checkNeighborsRefine_(const Element &entity, int level = 1) + { + // this also refines the neighbor elements + LeafIntersectionIterator isend = problem_.gridView().iend(entity); + for(LeafIntersectionIterator is = problem_.gridView().ibegin(entity); is != isend; ++is) + { + if(!is->neighbor()) + continue; + + ElementPointer outside = is->outside(); + + // only mark non-ghost elements + if (outside->partitionType() == Dune::GhostEntity) + continue; + + if ((outside->level() < levelMax_) + && (outside->level() < entity.level())) + { + problem_.grid().mark(1, *outside); + ++marked_; + + if(level != levelMax_) + checkNeighborsRefine_(*outside, ++level); + } + } + return true; + }; + + + /*! + * \brief Enforces a given refine ratio after grid was adapted + * + * If the refine ratio is not taken into consideration during + * marking, then this method ensures a certain ratio. + * + * @param maxLevelDelta The maximum level difference (refine ratio) + * between neighbors. + */ + void forceRefineRatio(int maxLevelDelta = 1) + { + LeafGridView leafView = problem_.gridView(); + // delete all existing marks + problem_.grid().postAdapt(); + bool done; + do + { + // run through all cells + done=true; + for (LeafIterator eIt = leafView.template begin<0>(); + eIt!=leafView.template end<0>(); ++eIt) + { + // only mark non-ghost elements + if (eIt->partitionType() == Dune::GhostEntity) + continue; + + // run through all neighbor-cells (intersections) + LeafIntersectionIterator isItend = leafView.iend(*eIt); + for (LeafIntersectionIterator isIt = leafView.ibegin(*eIt); isIt!= isItend; ++isIt) + { + const typename LeafIntersectionIterator::Intersection intersection = *isIt; + if(!intersection.neighbor()) + continue; + + ElementPointer outside =intersection.outside(); + if (eIt.level()+maxLevelDelta<outside.level()) + { + ElementPointer entity =eIt; + problem_.grid().mark( 1, *entity ); + done=false; + } + } + } + if (done==false) + { + // adapt the grid + problem_.grid().adapt(); + // delete marks + problem_.grid().postAdapt(); + } + } + while (done!=true); + } + + // private Variables + Problem& problem_; + AdaptionIndicator adaptionIndicator_; + + int marked_; + int coarsened_; + + int levelMin_; + int levelMax_; + + int adaptationInterval_; +}; + +/*! + * @brief Class for NON-adaptive simulations + * + * This class provides empty methods for non-adaptive simulations + * for compilation reasons. If adaptivity is desired, create the + * class with template arguments <TypeTag, true> instead. + */ +template<class TypeTag> +class ImplicitGridAdapt<TypeTag, false> +{ + typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; + typedef typename GET_PROP(TypeTag, SolutionVector) SolutionVector; + +public: + void init() + {}; + void adaptGrid() + {}; + bool wasAdapted() + { + return false; + } + void setLevels(int, int) + {}; + void setTolerance(int, int) + {}; + const void setIndicator(const SolutionVector&, + const Scalar&, const Scalar&) + {}; + ImplicitGridAdapt (Problem& problem) + {} +}; + +} +#endif /* DUMUX_IMPLICIT_GRIDADAPT_HH */ diff --git a/dumux/implicit/common/gridadaptproperties.hh b/dumux/implicit/common/gridadaptproperties.hh new file mode 100644 index 0000000000000000000000000000000000000000..28cd1888b7a0d2d324c3b15c21249f7e76ddd6a9 --- /dev/null +++ b/dumux/implicit/common/gridadaptproperties.hh @@ -0,0 +1,85 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \ingroup IMPETProperties + * \ingroup IMPET + * \file + * + * \brief Defines a type tag and some fundamental properties for + * linear solvers + */ +#ifndef DUMUX_IMPLICIT_GRIDADAPT_PROPERTIES_HH +#define DUMUX_IMPLICIT_GRIDADAPT_PROPERTIES_HH + +#include <dumux/common/basicproperties.hh> + +namespace Dumux +{ +namespace Properties +{ +//! Grid adaption type tag for all decoupled models. +NEW_TYPE_TAG(GridAdapt); + +//! Defines if the grid is h-adaptive +NEW_PROP_TAG(AdaptiveGrid); + +//! Class defining the refinement/coarsening indicator +NEW_PROP_TAG(AdaptionIndicator); + +//! Class defining the refinement/coarsening indicator for grid initialization +NEW_PROP_TAG(AdaptionInitializationIndicator); + +//! Switch the use of initial grid adaption on/off +NEW_PROP_TAG(GridAdaptEnableInitializationIndicator); + +//! Mimimum allowed level +NEW_PROP_TAG(GridAdaptMinLevel); + +//! Maximum allowed level +NEW_PROP_TAG(GridAdaptMaxLevel); + +//! Tolerance for refinement +NEW_PROP_TAG(GridAdaptRefineTolerance); + +//! Tolerance for coarsening +NEW_PROP_TAG(GridAdaptCoarsenTolerance); + +//! Tolerance for refinement +NEW_PROP_TAG(GridAdaptRefineThreshold); + +//! Tolerance for coarsening +NEW_PROP_TAG(GridAdaptCoarsenThreshold); + +//! Time step interval for adaption +NEW_PROP_TAG(GridAdaptAdaptionInterval); + +//! Switch for refinement at Dirichlet BC's -> not used by all indicators! +NEW_PROP_TAG(GridAdaptRefineAtDirichletBC); + +//! Switch for refinement at Neumann BC's -> not used by all indicators! +NEW_PROP_TAG(GridAdaptRefineAtFluxBC); + +//! Switch for refinement at sources -> not used by all indicators! +NEW_PROP_TAG(GridAdaptRefineAtSource); + +} // namespace Properties +} // namespace Dumux + + +#endif diff --git a/dumux/implicit/common/gridadaptpropertydefaults.hh b/dumux/implicit/common/gridadaptpropertydefaults.hh new file mode 100644 index 0000000000000000000000000000000000000000..623ee557c4da28d110ceb8056905065febe2d3ca --- /dev/null +++ b/dumux/implicit/common/gridadaptpropertydefaults.hh @@ -0,0 +1,69 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \ingroup IMPETProperties + * \ingroup IMPET + * \file + * + * \brief Defines a type tag and some fundamental properties for + * linear solvers + */ +#ifndef DUMUX_IMPLICIT_GRIDADAPT_PROPERTY_DEFAULTS_HH +#define DUMUX_IMPLICIT_GRIDADAPT_PROPERTY_DEFAULTS_HH + +#include <dumux/common/basicproperties.hh> +#include "gridadaptproperties.hh" +#include "gridadaptindicatordefault.hh" +#include "gridadaptinitializationindicatordefault.hh" +//#include "gridadaptinitializationindicator.hh" + +namespace Dumux +{ +namespace Properties +{ + +//no adaptive grid +SET_BOOL_PROP(GridAdapt, AdaptiveGrid, false); + +//standard setting +SET_INT_PROP(GridAdapt, GridAdaptMinLevel, 0); +SET_INT_PROP(GridAdapt, GridAdaptMaxLevel, 1); +SET_SCALAR_PROP(GridAdapt, GridAdaptRefineTolerance, 0.05); +SET_SCALAR_PROP(GridAdapt, GridAdaptCoarsenTolerance, 0.001); +SET_SCALAR_PROP(GridAdapt, GridAdaptRefineThreshold, 0.0); +SET_SCALAR_PROP(GridAdapt, GridAdaptCoarsenThreshold, 0.0); +SET_INT_PROP(GridAdapt, GridAdaptAdaptionInterval, 1); +//Switch initial grid adaption off per default +SET_BOOL_PROP(GridAdapt, GridAdaptEnableInitializationIndicator, false); + +// Switch of extra refinement strategy at boundaries/sources +SET_BOOL_PROP(GridAdapt, GridAdaptRefineAtDirichletBC, false); +SET_BOOL_PROP(GridAdapt, GridAdaptRefineAtFluxBC, false); +SET_BOOL_PROP(GridAdapt, GridAdaptRefineAtSource, false); + +//! Set the default indicator class models for adaption or coarsening +SET_TYPE_PROP(GridAdapt, AdaptionIndicator, ImplicitGridAdaptIndicatorDefault<TypeTag>); +//!Set default class for adaptation initialization indicator +SET_TYPE_PROP(GridAdapt, AdaptionInitializationIndicator, ImplicitGridAdaptInitializationIndicatorDefault<TypeTag>); + +} // namespace Properties +} // namespace Dumux + + +#endif