diff --git a/dumux/common/basicproperties.hh b/dumux/common/basicproperties.hh index 13cfaa80fc2369dc68a4d76fc9a6d82c66036feb..7b25c7f33646483ead4f62fdffcf522a97c241bd 100644 --- a/dumux/common/basicproperties.hh +++ b/dumux/common/basicproperties.hh @@ -30,7 +30,7 @@ #include <dumux/common/propertysystem.hh> #include <dumux/common/parameters.hh> -#include <dumux/io/dgfgridcreator.hh> +#include <dumux/io/gridcreator.hh> #include <dumux/io/vtkmultiwriter.hh> namespace Dumux @@ -72,6 +72,9 @@ NEW_PROP_TAG(ParameterTree); //! Property which defines the group that is queried for parameters by default NEW_PROP_TAG(ModelParameterGroup); +//! Property which defines the group that is queried for grid (creator) parameters by default +NEW_PROP_TAG(GridParameterGroup); + //! Property which provides a GridCreator (manages grids) NEW_PROP_TAG(GridCreator); @@ -151,8 +154,11 @@ SET_PROP(NumericModel, ParameterTree) //! use the global group as default for the model's parameter group SET_STRING_PROP(NumericModel, ModelParameterGroup, ""); +//! use the Grid group as default for the grid parameter group +SET_STRING_PROP(NumericModel, GridParameterGroup, "Grid"); + //! Use the DgfGridCreator by default -SET_TYPE_PROP(NumericModel, GridCreator, Dumux::DgfGridCreator<TypeTag>); +SET_TYPE_PROP(NumericModel, GridCreator, Dumux::GridCreator<TypeTag>); //! Set default output level to 0 -> only primary variables are added to output SET_INT_PROP(NumericModel, VtkOutputLevel, 0); diff --git a/dumux/common/parameters.hh b/dumux/common/parameters.hh index 2dadffd0603ffbf7e4d2e16da9db859fe5b253c3..926624b3d9c53dbfb9a4d3b5e7bb5b25f9c7f8fd 100644 --- a/dumux/common/parameters.hh +++ b/dumux/common/parameters.hh @@ -109,6 +109,37 @@ #define GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, ParamType, GroupName, ParamName) \ ::Dumux::Parameters::getRuntime<TypeTag, ParamType>(#GroupName, #ParamName) +/*! + * \ingroup Parameter + * \brief Retrieve a runtime parameter which _does not_ have a default value taken from + * the Dumux property system. + * + * The third argument is group name, which has to be a c-string + * This allows to use string variables as group name. The functionality of having varaibles as + * group name is no problem when directly using the Dune::ParameterTree. For consistency with the + * macro way of reading in the parameters this macro is necessary e.g. in the gridcreator to reach + * a satisfying level of generality. + * + * Example with a temporary c-string: + * + * \code + * // -> retrieves global integer value "NumberOfCellsX" which is + * // located in the parameter group "Grid" + * GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, "Grid", NumberOfCellsX); + * \endcode + * + * Example with a string variable: + * + * \code + * // -> retrieves global integer value "NumberOfCellsX" which is + * // located in the parameter group "Grid" + * std::string groupName = "Grid"; + * GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, groupName.c_str(), NumberOfCellsX); + * \endcode + */ +#define GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, ParamType, GroupName, ParamName) \ + ::Dumux::Parameters::getRuntime<TypeTag, ParamType>(GroupName, #ParamName) + namespace Dumux { namespace Properties diff --git a/dumux/io/gridcreator.hh b/dumux/io/gridcreator.hh new file mode 100644 index 0000000000000000000000000000000000000000..b888fab91af9b04a5a4a3fe3a6ae2996e3852c02 --- /dev/null +++ b/dumux/io/gridcreator.hh @@ -0,0 +1,1039 @@ +// -*- 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 Provides a grid creator for all supported grid managers with + * input file interfaces. + */ +#ifndef DUMUX_GRID_CREATOR_HH +#define DUMUX_GRID_CREATOR_HH + +#include <array> +#include <bitset> +#include <memory> +#include <sstream> + +#include <dune/common/exceptions.hh> +#include <dune/common/version.hh> +#include <dune/common/parallel/collectivecommunication.hh> +#include <dune/common/parallel/mpihelper.hh> +#include <dune/grid/io/file/dgfparser/dgfparser.hh> +#include <dune/grid/io/file/gmshreader.hh> +#include <dune/grid/common/gridfactory.hh> +#include <dune/grid/utility/structuredgridfactory.hh> + +// YaspGrid specific includes +#include <dune/grid/yaspgrid.hh> +#include <dune/grid/io/file/dgfparser/dgfyasp.hh> + + // OneDGrid specific includes +#include <dune/grid/onedgrid.hh> +#include <dune/grid/io/file/dgfparser/dgfoned.hh> + +// UGGrid specific includes +#if HAVE_UG +#include <dune/grid/uggrid.hh> +#include <dune/grid/io/file/dgfparser/dgfug.hh> +#endif + +// ALUGrid specific includes +#if HAVE_DUNE_ALUGRID +#include <dune/alugrid/grid.hh> +#include <dune/alugrid/dgf.hh> +#endif + +// FoamGrid specific includes +#if HAVE_DUNE_FOAMGRID +#include <dune/foamgrid/foamgrid.hh> +#include <dune/foamgrid/dgffoam.cc> +#endif + +// Alberta specific includes +#if HAVE_ALBERTA +#include <dune/grid/albertagrid.hh> +#include <dune/albertagrid/dgfparser.hh> +#endif + +#include <dumux/common/propertysystem.hh> +#include <dumux/common/parameters.hh> + +namespace Dumux +{ +namespace Properties +{ +// poperty forward declarations +NEW_PROP_TAG(Grid); +NEW_PROP_TAG(GridParameterGroup); +} + + +/*! + * \brief Provides the grid creator base interface (public) and methods common + * to most grid creator specializations (protected). + */ +template <class TypeTag, class Grid> +class GridCreatorBase +{ +public: + + /*! + * \brief Returns a reference to the grid. + */ + static Grid &grid() + { + if(enableDgfGridPointer_) + return *dgfGridPtr(); + else + return *gridPtr(); + } + + /*! + * \brief Call the parameters function of the DGF grid pointer if available + */ + template <class Entity> + static const std::vector<double>& parameters(const Entity& entity) + { + if(enableDgfGridPointer_) + return dgfGridPtr().parameters(entity); + else + DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file!"); + } + + /*! + * \brief Call the parameters function of the DGF grid pointer if available + */ + template <class GridImp, class IntersectionImp> + static const Dune::DGFBoundaryParameter::type& parameters(const Dune::Intersection<GridImp, IntersectionImp>& intersection) + { + if(enableDgfGridPointer_) + return dgfGridPtr().parameters(intersection); + else + DUNE_THROW(Dune::InvalidStateException, "The parameters method is only available if the grid was constructed with a DGF file!"); + } + + /*! + * \brief Call loadBalance() function of the grid. + */ + static void loadBalance() + { + if(enableDgfGridPointer_) + dgfGridPtr().loadBalance(); + else + gridPtr()->loadBalance(); + } + +protected: + + /*! + * \brief Returns a reference to the grid pointer (std::shared_ptr<Grid>) + */ + static std::shared_ptr<Grid> &gridPtr() + { + if(!enableDgfGridPointer_) + { + static std::shared_ptr<Grid> gridPtr_; + return gridPtr_; + } + else + DUNE_THROW(Dune::InvalidStateException, "You are using DGF. To get the grid pointer use method dgfGridPtr()!"); + } + + /*! + * \brief Returns a reference to the dgf grid pointer (Dune::GridPtr<Grid>). + */ + static Dune::GridPtr<Grid> &dgfGridPtr() + { + if(enableDgfGridPointer_) + { + static Dune::GridPtr<Grid> dgfGridPtr_; + return dgfGridPtr_; + } + else + DUNE_THROW(Dune::InvalidStateException, "The dgf grid pointer is only available if the grid was constructed with a DGF file!"); + } + + /*! + * \brief Returns the filename extension of a given filename + */ + static std::string getFileExtension(const std::string& fileName) + { + std::size_t i = fileName.rfind('.', fileName.length()); + if (i != std::string::npos) + { + return(fileName.substr(i+1, fileName.length() - i)); + } + else + { + DUNE_THROW(Dune::IOError, "Please provide and extension for your grid file ('"<< fileName << "')!"); + } + return ""; + } + + /*! + * \brief Makes a grid from a file. We currently support *.dgf (Dune Grid Format) and *.msh (Gmsh mesh format). + */ + static void makeGridFromFile(const std::string& fileName, const std::string& gridName) + { + // We found a file in the input file...does it have a supported extension? + const std::string extension = getFileExtension(fileName); + if(extension != "dgf" && extension != "msh") + DUNE_THROW(Dune::IOError, "Grid manager " << gridName << " only supports DGF (*.dgf) and Gmsh (*.msh) grid files but the specified filename has extension: *."<< extension); + + // make the grid + if(extension == "dgf") + { + enableDgfGridPointer_ = true; + dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator()); + } + if(extension == "msh") + { + // get some optional parameters + bool verbose = false; + try { verbose = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Verbose);} + catch (Dumux::ParameterException &e) { } + + bool boundarySegments = false; + try { boundarySegments = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), BoundarySegments);} + catch (Dumux::ParameterException &e) { } + + gridPtr() = std::shared_ptr<Grid>(Dune::GmshReader<Grid>::read(fileName, verbose, boundarySegments)); + } + } + + /*! + * \brief Makes a grid from a DGF file. This is used by grid managers that only support DGF. + */ + static void makeGridFromDgfFile(const std::string& fileName, const std::string& gridName) + { + // We found a file in the input file...does it have a supported extension? + const std::string extension = getFileExtension(fileName); + if(extension != "dgf") + DUNE_THROW(Dune::IOError, "Grid manager " << gridName << " only supports DGF (*.dgf) but the specified filename has extension: *."<< extension); + + enableDgfGridPointer_ = true; + dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator()); + } + + /*! + * \brief The cell types for structured grids + */ + enum CellType {Simplex, Cube}; + + /*! + * \brief Makes a structured cube grid using the structured grid factory + */ + template <int dim, int dimworld> + static void makeStructuredGrid(CellType cellType) + { + // The required parameters + typedef Dune::FieldVector<typename Grid::ctype, dimworld> GlobalPosition; + const GlobalPosition lowerLeft = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), LowerLeft); + const GlobalPosition upperRight = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), UpperRight); + + // The optional parameters (they have a default) + typedef std::array<unsigned int, dim> CellArray; + CellArray cells; + std::fill(cells.begin(), cells.end(), 1); + try { cells = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Cells); } + catch (Dumux::ParameterException &e) { } + + // make the grid + Dune::StructuredGridFactory<Grid> factory; + if (cellType == CellType::Cube) + { + gridPtr() = factory.createCubeGrid(lowerLeft, upperRight, cells); + } + if (cellType == CellType::Simplex) + { + gridPtr() = factory.createSimplexGrid(lowerLeft, upperRight, cells); + } + } + + /*! + * \brief Refines a grid after construction if GridParameterGroup.Refinement is set in the input file + */ + static void maybeRefineGrid() + { + try { + const int level = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Refinement); + grid().globalRefine(level); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + } + + /*! + * \brief A state variable if the DGF Dune::GridPtr has been enabled. + * It is always enabled if a DGF grid file was used to create the grid. + */ + static bool enableDgfGridPointer_; +}; + +template <class TypeTag, class Grid> +bool GridCreatorBase<TypeTag, Grid>::enableDgfGridPointer_ = false; + +/*! + * \brief Provides the grid creator implementation for all supported grid managers that constructs a grid + * from information in the input file. This class is specialised below for all + * supported grid managers. It inherits the functionality of the base class. + */ +template <class TypeTag, class Grid> +class GridCreatorImpl : public GridCreatorBase<TypeTag, Grid> +{ +public: + /*! + * \brief Make the grid. This is implemented by specializations of this class. + */ + static void makeGrid() + { + DUNE_THROW(Dune::NotImplemented, + "The GridCreator for this Grid manager is not implemented! Consider providing your own GridCreator."); + } +}; + +/*! + * \brief Provides the grid creator (this is the class called by the user) for all supported grid managers that constructs a grid + * from information in the input file. This class is specialised below for all + * supported grid managers. It inherits the functionality of the base class. + */ +template <class TypeTag> +class GridCreator : public GridCreatorImpl<TypeTag, typename GET_PROP_TYPE(TypeTag, Grid)> +{}; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Specializations ////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4) + +/*! + * \brief Provides a grid creator for YaspGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + * The following keys are recognized: + * - File : a DGF file to load the coarse grid from + * - UpperRight : extension of the domain + * - Cells : the number of cells in each direction + * - Periodic : true or false for each direction + * - Overlap : overlap size in cells + * - Partitioning : a non-standard load-balancing, number of processors per direction + * - KeepPyhsicalOverlap : whether to keep the physical overlap + * in physical size or in number of cells upon refinement + * - Refinement : the number of global refines to apply initially. + * + */ +template<class TypeTag, class ct, int dim> +class GridCreatorImpl<TypeTag, Dune::YaspGrid<dim, Dune::EquidistantCoordinates<ct, dim> > > + : public GridCreatorBase<TypeTag, Dune::YaspGrid<dim, Dune::EquidistantCoordinates<ct, dim> > > +{ +public: + typedef typename Dune::YaspGrid<dim, Dune::EquidistantCoordinates<ct, dim> > Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromDgfFile(fileName, "YaspGrid"); + postProcessing_(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct from the input file + try { + // The required parameters + typedef Dune::FieldVector<ct, dim> GlobalPosition; + const GlobalPosition upperRight = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), UpperRight); + + // The optional parameters (they have a default) + typedef std::array<int, dim> CellArray; + CellArray cells; + std::fill(cells.begin(), cells.end(), 1); + try { cells = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Cells); } + catch (Dumux::ParameterException &e) { } + + typedef std::bitset<dim> BitSet; + BitSet periodic; + try { periodic = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, BitSet, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Periodic);} + catch (Dumux::ParameterException &e) { } + + int overlap = 1; + try { overlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Overlap);} + catch (Dumux::ParameterException &e) { } + + bool default_lb = false; + CellArray partitioning; + try { partitioning = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Partitioning);} + catch (Dumux::ParameterException &e) { default_lb = true; } + + //make the grid + if (default_lb) + ParentType::gridPtr() = std::make_shared<Grid>(upperRight, cells, periodic, overlap); + else + { + typename Dune::YaspFixedSizePartitioner<dim> lb(partitioning); + ParentType::gridPtr() = std::make_shared<Grid>(upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); + } + postProcessing_(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameter " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } + +private: + /*! + * \brief Postprocessing for YaspGrid + */ + static void postProcessing_() + { + // Check if should refine the grid + bool keepPhysicalOverlap = true; + try { keepPhysicalOverlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), KeepPhysicalOverlap);} + catch (Dumux::ParameterException &e) { } + ParentType::grid().refineOptions(keepPhysicalOverlap); + ParentType::maybeRefineGrid(); + } +}; + +/*! + * \brief Provides a grid creator for YaspGrids with non-zero offset + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + * The following keys are recognized: + * - LowerLeft : lower left corner coordinates + * - UpperRight : upper right corner coordinates + * - Cells : the number of cells in each direction + * - Periodic : true or false for each direction + * - Overlap : overlap size in cells + * - Partitioning : a non-standard load-balancing, number of processors per direction + * - KeepPyhsicalOverlap : whether to keep the physical overlap + * in physical size or in number of cells upon refinement + * - Refinement : the number of global refines to apply initially. + * + */ +template<class TypeTag, class ct, int dim> +class GridCreatorImpl<TypeTag, Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<ct, dim> > > + : public GridCreatorBase<TypeTag, Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<ct, dim> > > +{ +public: + typedef typename Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<ct, dim> > Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // Only construction from the input file is possible + // Look for the necessary keys to construct from the input file + try { + // The required parameters + typedef Dune::FieldVector<ct, dim> GlobalPosition; + const GlobalPosition lowerLeft = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), LowerLeft); + const GlobalPosition upperRight = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), UpperRight); + + // The optional parameters (they have a default) + typedef std::array<int, dim> CellArray; + CellArray cells; + std::fill(cells.begin(), cells.end(), 1); + try { cells = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Cells); } + catch (Dumux::ParameterException &e) { } + + typedef std::bitset<dim> BitSet; + BitSet periodic; + try { periodic = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, BitSet, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Periodic);} + catch (Dumux::ParameterException &e) { } + + int overlap = 1; + try { overlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Overlap);} + catch (Dumux::ParameterException &e) { } + + bool default_lb = false; + CellArray partitioning; + try { partitioning = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Partitioning);} + catch (Dumux::ParameterException &e) { default_lb = true; } + + //make the grid + if (default_lb) + ParentType::gridPtr() = std::make_shared<Grid>(lowerLeft, upperRight, cells, periodic, overlap); + else + { + typename Dune::YaspFixedSizePartitioner<dim> lb(partitioning); + ParentType::gridPtr() = std::make_shared<Grid>(lowerLeft, upperRight, cells, periodic, overlap, typename Grid::CollectiveCommunicationType(), &lb); + } + postProcessing_(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight, " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } + +private: + /*! + * \brief Postprocessing for YaspGrid + */ + static void postProcessing_() + { + // Check if should refine the grid + bool keepPhysicalOverlap = true; + try { keepPhysicalOverlap = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, bool, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), KeepPhysicalOverlap);} + catch (Dumux::ParameterException &e) { } + ParentType::grid().refineOptions(keepPhysicalOverlap); + ParentType::maybeRefineGrid(); + } +}; + +#else + +/*! + * \brief Provides a grid creator for YaspGrids (Dune 2.3) + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + * The following keys are recognized: + * - File : a DGF file to load the coarse grid from + * - Refinement : the number of global refines to apply initially. + * + */ +template<class TypeTag, int dim> +class GridCreatorImpl<TypeTag, Dune::YaspGrid<dim> > + : public GridCreatorBase<TypeTag, Dune::YaspGrid<dim> > +{ +public: + typedef typename Dune::YaspGrid<dim> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // Try to create it from a DGF file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromDgfFile(fileName, "YaspGrid"); + ParentType::maybeRefineGrid(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + } +}; + +#endif + +/*! + * \brief Provides a grid creator for OneDGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + * The following keys are recognized: + * - LeftBoundary : start coordinate + * - RightBoundary : end coordinate + * - Cells : the number of cell + * - RefinementType : local or copy + * - Refinement : the number of global refines to apply initially. + * + */ +template<class TypeTag> +class GridCreatorImpl<TypeTag, Dune::OneDGrid> + : public GridCreatorBase<TypeTag, Dune::OneDGrid> +{ +public: + typedef typename Dune::OneDGrid Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromDgfFile(fileName, "OneDGrid"); + postProcessing_(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Look for the necessary keys to construct from the input file + try { + // The required parameters + typedef typename Grid::ctype Coordinate; + const Coordinate leftBoundary = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, Coordinate, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), LeftBoundary); + const Coordinate rightBoundary = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, Coordinate, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), RightBoundary); + + // The optional parameters + int cells = 1; + try { cells = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Cells);} + catch (Dumux::ParameterException &e) { } + + ParentType::gridPtr() = std::make_shared<Grid>(cells, leftBoundary, rightBoundary); + postProcessing_(); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Look for the necessary keys to construct from the input file with just a coordinates vector + try { + // The required parameters + typedef std::vector<typename Grid::ctype> Coordinates; + const Coordinates coordinates = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, Coordinates, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Coordinates); + // make the grid + ParentType::gridPtr() = std::make_shared<Grid>(coordinates); + postProcessing_(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LeftBoundary, " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".RightBoundary or " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".Coordinates or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } + +private: + /*! + * \brief Do some operatrion after making the grid, like global refinement + */ + static void postProcessing_() + { + // Check for refinement type + std::string refType = "Local"; + try { refType = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), RefinementType); + if (refType != "Local" && refType != "Copy") + DUNE_THROW(Dune::IOError, "OneGrid only supports 'Local' or 'Copy' as refinment type. Not '"<< refType<<"'!"); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + if (refType == "Local") + ParentType::grid().setRefinementType(Dune::OneDGrid::RefinementType::LOCAL); + if (refType == "Copy") + ParentType::grid().setRefinementType(Dune::OneDGrid::RefinementType::COPY); + + // Check if should refine the grid + ParentType::maybeRefineGrid(); + } +}; + +#if HAVE_UG + +/*! + * \brief Provides a grid creator for UGGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + + * The following keys are recognized: + * - File : A DGF or gmsh file to load from, type detection by file extension + * - LowerLeft : lowerleft corner of a structured grid + * - UpperRight : upperright corner of a structured grid + * - Cells : number of elements in a structured grid + * - CellType : "Cube" or "Simplex" to be used for structured grids + * - Refinement : the number of global refines to perform + * - Verbose : whether the grid construction should output to standard out + * - HeapSize: The heapsize used to allocate memory + * - BoundarySegments : whether to insert boundary segments into the grid + * + */ +template<class TypeTag, int dim> +class GridCreatorImpl<TypeTag, Dune::UGGrid<dim> > + : public GridCreatorBase<TypeTag, Dune::UGGrid<dim> > +{ +public: + typedef typename Dune::UGGrid<dim> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the UGGrid. + */ + static void makeGrid() + { + // First try to create it from a DGF or msh file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + preProcessing_(); + ParentType::makeGridFromFile(fileName, "UGGrid"); + postProcessing_(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct from the input file + try { + preProcessing_(); + // Check for cell type + std::string cellType = "Cube"; + try { cellType = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), CellType); + if (cellType != "Cube" && cellType != "Simplex") + DUNE_THROW(Dune::IOError, "UGGrid only supports 'Cube' or 'Simplex' as closure type. Not '"<< cellType<<"'!"); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // make the grid + if (cellType == "Cube") + ParentType::template makeStructuredGrid<dim, dim>(ParentType::CellType::Cube); + if (cellType == "Simplex") + ParentType::template makeStructuredGrid<dim, dim>(ParentType::CellType::Simplex); + postProcessing_(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight and " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } + +private: + /*! + * \brief Do some operatrion before making the grid + */ + static void preProcessing_() + { + bool setDefaultHeapSize = true; + unsigned defaultHeapSize; + try { defaultHeapSize = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, unsigned, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), HeapSize);} + catch (Dumux::ParameterException &e) { setDefaultHeapSize = false; } + + if(setDefaultHeapSize) + Grid::setDefaultHeapSize(defaultHeapSize); + } + + /*! + * \brief Do some operatrion after making the grid, like global refinement + */ + static void postProcessing_() + { + // Check for refinement type + std::string refType = "Local"; + try { refType = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), RefinementType); + if (refType != "Local" && refType != "Copy") + DUNE_THROW(Dune::IOError, "UGGrid only supports 'Local' or 'Copy' as refinment type. Not '"<< refType<<"'!"); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + if (refType == "Local") + ParentType::grid().setRefinementType(Dune::UGGrid<dim>::RefinementType::LOCAL); + if (refType == "Copy") + ParentType::grid().setRefinementType(Dune::UGGrid<dim>::RefinementType::COPY); + + // Check for closure type + std::string closureType = "Green"; + try { closureType = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, int, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), RefinementType); + if (closureType != "None" && closureType != "Green") + DUNE_THROW(Dune::IOError, "UGGrid only supports 'Green' or 'None' as closure type. Not '"<< closureType<<"'!"); + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + if (closureType == "Green") + ParentType::grid().setClosureType(Dune::UGGrid<dim>::ClosureType::GREEN); + if (closureType == "None") + ParentType::grid().setClosureType(Dune::UGGrid<dim>::ClosureType::NONE); + + // Check if should refine the grid + ParentType::maybeRefineGrid(); + } +}; + +#endif // HAVE_UG + +#if HAVE_DUNE_ALUGRID + +/*! + * \brief Provides a grid creator for Dune ALUGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + + * The following keys are recognized: + * - File : A DGF or gmsh file to load from, type detection by file extension + * - LowerLeft : lowerleft corner of a structured grid + * - UpperRight : upperright corner of a structured grid + * - Cells : number of elements in a structured grid + * - Refinement : the number of global refines to perform + * - Verbose : whether the grid construction should output to standard out + * - BoundarySegments : whether to insert boundary segments into the grid + * + */ +template<class TypeTag, int dim, int dimworld, Dune::ALUGridElementType elType, Dune::ALUGridRefinementType refinementType> +class GridCreatorImpl<TypeTag, Dune::ALUGrid<dim, dimworld, elType, refinementType> > + : public GridCreatorBase<TypeTag, Dune::ALUGrid<dim, dimworld, elType, refinementType> > +{ +public: + typedef typename Dune::ALUGrid<dim, dimworld, elType, refinementType> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF or msh file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromFile(fileName, "ALUGrid"); + ParentType::maybeRefineGrid(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct from the input file + try { + // make a structured grid + if (elType == Dune::cube) + ParentType::template makeStructuredGrid<dim, dimworld>(ParentType::CellType::Cube); + if (elType == Dune::simplex) + ParentType::template makeStructuredGrid<dim, dimworld>(ParentType::CellType::Simplex); + ParentType::maybeRefineGrid(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight and " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } +}; + +#endif // HAVE_DUNE_ALUGRID + +#if HAVE_DUNE_FOAMGRID + +/*! + * \brief Provides a grid creator for FoamGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + + * The following keys are recognized: + * - File : A DGF or gmsh file to load from, type detection by file extension + * - Verbose : whether the grid construction should output to standard out + * - LowerLeft : lowerleft corner of a structured grid + * - UpperRight : upperright corner of a structured grid + * - Cells : number of elements in a structured grid + * + */ +template<class TypeTag, int dim, int dimworld> +class GridCreatorImpl<TypeTag, Dune::FoamGrid<dim, dimworld> > + : public GridCreatorBase<TypeTag, Dune::FoamGrid<dim, dimworld> > +{ +public: + typedef typename Dune::FoamGrid<dim, dimworld> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF or msh file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromFile(fileName, "FoamGrid"); + ParentType::maybeRefineGrid(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct a structured grid from the input file + try { + ParentType::template makeStructuredGrid<dim, dimworld>(ParentType::CellType::Simplex); + ParentType::maybeRefineGrid(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight and " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } +}; + +/*! + * \brief Provides a grid creator for FoamGrids of dim 1 + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + + * The following keys are recognized: + * - File : A DGF or gmsh file to load from, type detection by file extension + * - Verbose : whether the grid construction should output to standard out + * - LowerLeft : lowerleft corner of a structured grid + * - UpperRight : upperright corner of a structured grid + * - Cells : number of elements in a structured grid + * + */ +template<class TypeTag, int dimworld> +class GridCreatorImpl<TypeTag, Dune::FoamGrid<1, dimworld> > + : public GridCreatorBase<TypeTag, Dune::FoamGrid<1, dimworld> > +{ +public: + typedef typename Dune::FoamGrid<1, dimworld> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF or msh file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromFile(fileName, "FoamGrid"); + ParentType::maybeRefineGrid(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct a structured grid from the input file + try { + // The required parameters + typedef Dune::FieldVector<typename Grid::ctype, dimworld> GlobalPosition; + const GlobalPosition lowerLeft = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), LowerLeft); + const GlobalPosition upperRight = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, GlobalPosition, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), UpperRight); + + // The optional parameters (they have a default) + typedef std::array<unsigned int, 1> CellArray; + CellArray cells; + std::fill(cells.begin(), cells.end(), 1); + try { cells = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, CellArray, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), Cells); } + catch (Dumux::ParameterException &e) { } + + // make the grid (structured interval grid in dimworld space) + Dune::GridFactory<Grid> factory; + Dune::GeometryType geomType(1); + + // create a step vector + GlobalPosition step = upperRight; + step -= lowerLeft, step /= cells[0]; + + // create the vertices + GlobalPosition globalPos = lowerLeft; + for (unsigned int vIdx = 0; vIdx <= cells[0]; vIdx++, globalPos += step) + factory.insertVertex(globalPos); + + // create the cells + for(unsigned int eIdx = 0; eIdx < cells[0]; eIdx++) + factory.insertElement(geomType, {eIdx, eIdx+1}); + + ParentType::gridPtr() = std::shared_ptr<Grid>(factory.createGrid()); + ParentType::maybeRefineGrid(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight and " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } +}; + +#endif // HAVE_DUNE_FOAMGRID + +#if HAVE_ALBERTA + +/*! + * \brief Provides a grid creator for FoamGrids + * from information in the input file + * + * All keys are expected to be in group GridParameterGroup. + + * The following keys are recognized: + * - File : A DGF or gmsh file to load from, type detection by file extension + * - Verbose : whether the grid construction should output to standard out + * + */ +template<class TypeTag, int dim, int dimworld> +class GridCreatorImpl<TypeTag, Dune::AlbertaGrid<dim, dimworld> > + : public GridCreatorBase<TypeTag, Dune::AlbertaGrid<dim, dimworld> > +{ +public: + typedef typename Dune::AlbertaGrid<dim, dimworld> Grid; + typedef GridCreatorBase<TypeTag, Grid> ParentType; + + /*! + * \brief Make the grid. This is implemented by specializations of this method. + */ + static void makeGrid() + { + // First try to create it from a DGF or msh file in GridParameterGroup.File + try { + const std::string fileName = GET_RUNTIME_PARAM_FROM_GROUP_CSTRING(TypeTag, std::string, GET_PROP_VALUE(TypeTag, GridParameterGroup).c_str(), File); + ParentType::makeGridFromFile(fileName, "Alberta"); + ParentType::maybeRefineGrid(); + return; + } + catch (Dumux::ParameterException &e) {} + catch (...) { throw; } + + // Then look for the necessary keys to construct a structured grid from the input file + try { + ParentType::template makeStructuredGrid<dim, dimworld>(ParentType::CellType::Simplex); + ParentType::maybeRefineGrid(); + } + catch (Dumux::ParameterException &e) { + DUNE_THROW(Dumux::ParameterException, "Please supply the mandatory parameters " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".UpperRight and " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".LowerLeft or a grid file in " + << GET_PROP_VALUE(TypeTag, GridParameterGroup) << ".File."); + } + catch (...) { throw; } + } +}; + +#endif // HAVE_ALBERTA + +// TODO support Yasp Tensor Product Grid +// TODO Petrel grids with dune-cornerpoint + +} // namespace Dumux + +#endif diff --git a/test/decoupled/2p/test_impesproblem.hh b/test/decoupled/2p/test_impesproblem.hh index a9e7b1b9cfa9a7c6af563a0e2511aa6916fd9945..be269e9b660678b59be31d0ed3447a66c3c878bd 100644 --- a/test/decoupled/2p/test_impesproblem.hh +++ b/test/decoupled/2p/test_impesproblem.hh @@ -26,6 +26,7 @@ #include <dune/grid/yaspgrid.hh> #include <dumux/io/cubegridcreator.hh> +#include <dumux/io/gridcreator.hh> #include <dumux/material/fluidsystems/liquidphase.hh> #include <dumux/material/components/simpleh2o.hh> @@ -43,7 +44,7 @@ #include "test_impesspatialparams.hh" -#include<dumux/decoupled/2p/transport/fv/evalcflfluxcoats.hh> +#include <dumux/decoupled/2p/transport/fv/evalcflfluxcoats.hh> #include <dumux/linear/amgbackend.hh> @@ -117,8 +118,8 @@ NEW_TYPE_TAG(IMPESTestProblemWithAMG, INHERITS_FROM(IMPESTestProblem)); SET_TYPE_PROP(IMPESTestProblemWithAMG, LinearSolver, Dumux::AMGBackend<TypeTag>); // Set the grid type SET_TYPE_PROP(IMPESTestProblemWithAMG, Grid, Dune::YaspGrid<2>); -// set the GridCreator property -SET_TYPE_PROP(IMPESTestProblemWithAMG, GridCreator, Dumux::DgfGridCreator<TypeTag>); +// Set the grid creator +SET_TYPE_PROP(IMPESTestProblemWithAMG, GridCreator, Dumux::GridCreator<TypeTag>); } /*!