// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #ifndef DUNE_MULTIMESH_GRIDFACTORY_HH #define DUNE_MULTIMESH_GRIDFACTORY_HH #include #include #include #include #include #include #include "multimesh.hh" namespace Dune { /** \brief specialization of the generic GridFactory for MultiMesh * \ingroup GridFactory */ template class GridFactory > : public GridFactoryInterface > { public: /// Type of grid this factory is for using Grid = MultiMesh; /// Type of (scalar) coordinates using ctype = typename Grid::ctype; /// dimension of the grid static const int dimension = Grid::dimension; /// dimension of the world static const int dimensionworld = Grid::dimensionworld; using LocalCoordinate = FieldVector; using GlobalCoordinate = FieldVector; using BoundarySegment = Dune::BoundarySegment; using ElementParametrization = VirtualFunction; public: /// \brief Constructor /** * \param[in] n The number of grids to construct * \param[in] args Additional parameters passed to the constructor of the * hostgridfactory **/ template explicit GridFactory (std::size_t n, Args&&... args) { for (std::size_t i = 0; i < n; ++i) gridFactories_.emplace_back(new GridFactory{args...}); } // initialize at least 1 grid GridFactory () : GridFactory{1} {} /// \brief Insert a vertex into the macro grid /** * \param[in] pos Position of the vertex (in world coordinates) **/ virtual void insertVertex (const GlobalCoordinate& pos) override { for (auto& gridFactory : gridFactories_) gridFactory->insertVertex(pos); } /// \brief Insert an element into the coarse grid /** * \param[in] type GeometryType of the new element * \param[in] vertices Indices of the element vertices **/ virtual void insertElement (const GeometryType& type, const std::vector& vertices) override { for (auto& gridFactory : gridFactories_) gridFactory->insertElement(type, vertices); } template using HasInsertElement = decltype( std::declval().insertElement( std::declval(), std::declval>(), std::declval>()) ); /// \brief Insert a parametrized element into the coarse grid /** * \param[in] type The GeometryType of the new element * \param[in] vertices The vertices of the new element * \param[in] param A function prescribing the shape of this element **/ virtual void insertElement ( const GeometryType& type, const std::vector& vertices, const std::shared_ptr& param) override { Hybrid::ifElse(Std::is_detected>{}, [&](auto id) { for (auto& gridFactory : gridFactories_) id(gridFactory)->insertElement(type, vertices, param); }); } /// \brief Insert a boundary segment into the macro grid /** * Only influences the ordering of the boundary segments * \param[in] vertices Vertex indices of boundary face **/ virtual void insertBoundarySegment ( const std::vector& vertices) override { for (auto& gridFactory : gridFactories_) gridFactory->insertBoundarySegment(vertices); } template using HasInsertBoundarySegment = decltype( std::declval().insertBoundarySegment( std::declval>(), std::declval>()) ); /** \brief Insert a shaped boundary segment into the macro grid * * \param[in] vertices Vertex indices of boundary face * \param[in] boundarySegment Geometric realization of shaped boundary */ virtual void insertBoundarySegment ( const std::vector& vertices, const std::shared_ptr& boundarySegment) override { Hybrid::ifElse(Std::is_detected>{}, [&](auto id) { for (auto& gridFactory : gridFactories_) id(gridFactory)->insertBoundarySegment(vertices, boundarySegment); }); } /// \brief Finalize grid creation and hand over the grid /** * Create n copies of the grid and store it in unique_pointers * inside the multimesh grid. **/ virtual Grid* createGrid () override { Grid* multimesh = new Grid{}; for (auto& gridFactory : gridFactories_) multimesh->grids_.emplace_back(gridFactory->createGrid()); return multimesh; } private: std::vector>> gridFactories_; }; } // end namespace Dune #endif // DUNE_MULTIMESH_GRIDFACTORY_HH