mmgridfactory.hh 5.63 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6
// -*- 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 <memory>
7
#include <type_traits>
Praetorius, Simon's avatar
Praetorius, Simon committed
8 9
#include <vector>

10
#include <dune/common/hybridutilities.hh>
11 12
#include <dune/common/to_unique_ptr.hh>
#include <dune/common/version.hh>
13
#include <dune/common/std/type_traits.hh>
Praetorius, Simon's avatar
Praetorius, Simon committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include <dune/grid/common/gridfactory.hh>

#include "multimesh.hh"

namespace Dune
{
  /** \brief specialization of the generic GridFactory for MultiMesh
   *  \ingroup GridFactory
   */
  template <class HostGrid>
  class GridFactory<MultiMesh<HostGrid> >
      : public GridFactoryInterface<MultiMesh<HostGrid> >
  {
  public:
    /// Type of grid this factory is for
    using Grid = MultiMesh<HostGrid>;

    /// 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<ctype, dimension>;
    using GlobalCoordinate = FieldVector<ctype, dimensionworld>;

    using BoundarySegment = Dune::BoundarySegment<dimension, dimensionworld>;
44
    using ElementParametrization = VirtualFunction<LocalCoordinate, GlobalCoordinate>;
Praetorius, Simon's avatar
Praetorius, Simon committed
45 46 47 48 49

  public:
    /// \brief Constructor
    /**
     * \param[in]  n     The number of grids to construct
50 51
     * \param[in]  args  Additional parameters passed to the constructor of the
     *                   hostgridfactory
Praetorius, Simon's avatar
Praetorius, Simon committed
52 53 54
     **/
    template <class... Args>
    explicit GridFactory (std::size_t n, Args&&... args)
55 56
    {
      for (std::size_t i = 0; i < n; ++i)
57
        gridFactories_.emplace_back(new GridFactory<HostGrid>{args...});
58
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
59

60 61 62 63 64
    // initialize at least 1 grid
    GridFactory ()
      : GridFactory{1}
    {}

65
    /// \brief Insert a vertex into the macro grid
Praetorius, Simon's avatar
Praetorius, Simon committed
66
    /**
67
     *  \param[in]  pos  Position of the vertex (in world coordinates)
Praetorius, Simon's avatar
Praetorius, Simon committed
68
     **/
69
    virtual void insertVertex (const GlobalCoordinate& pos) override
Praetorius, Simon's avatar
Praetorius, Simon committed
70 71
    {
      for (auto& gridFactory : gridFactories_)
72
        gridFactory->insertVertex(pos);
Praetorius, Simon's avatar
Praetorius, Simon committed
73 74
    }

75
    /// \brief Insert an element into the coarse grid
Praetorius, Simon's avatar
Praetorius, Simon committed
76 77
    /**
     *  \param[in]  type      GeometryType of the new element
78
     *  \param[in]  vertices  Indices of the element vertices
Praetorius, Simon's avatar
Praetorius, Simon committed
79 80
     **/
    virtual void insertElement (const GeometryType& type,
81
                                const std::vector<unsigned int>& vertices) override
Praetorius, Simon's avatar
Praetorius, Simon committed
82 83
    {
      for (auto& gridFactory : gridFactories_)
84
        gridFactory->insertElement(type, vertices);
Praetorius, Simon's avatar
Praetorius, Simon committed
85 86
    }

87 88 89 90 91 92 93

    template <class GF>
    using HasInsertElement = decltype( std::declval<GF>().insertElement(
      std::declval<GeometryType>(),
      std::declval<std::vector<unsigned int>>(),
      std::declval<std::shared_ptr<ElementParametrization>>()) );

Praetorius, Simon's avatar
Praetorius, Simon committed
94 95
    /// \brief Insert a parametrized element into the coarse grid
    /**
96 97 98
     *   \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
Praetorius, Simon's avatar
Praetorius, Simon committed
99
     **/
100 101 102 103 104 105 106 107
    virtual void insertElement (
        const GeometryType& type,
        const std::vector<unsigned int>& vertices,
        const std::shared_ptr<ElementParametrization>& param) override
    {
      Hybrid::ifElse(Std::is_detected<HasInsertElement, GridFactory<HostGrid>>{},
      [&](auto id) {
        for (auto& gridFactory : gridFactories_)
108
          id(gridFactory)->insertElement(type, vertices, param);
109 110 111 112
      });
    }

    /// \brief Insert a boundary segment into the macro grid
Praetorius, Simon's avatar
Praetorius, Simon committed
113 114
    /**
     *  Only influences the ordering of the boundary segments
115
     *  \param[in]  vertices  Vertex indices of boundary face
Praetorius, Simon's avatar
Praetorius, Simon committed
116
     **/
117 118
    virtual void insertBoundarySegment (
        const std::vector<unsigned int>& vertices) override
Praetorius, Simon's avatar
Praetorius, Simon committed
119 120
    {
      for (auto& gridFactory : gridFactories_)
121
        gridFactory->insertBoundarySegment(vertices);
Praetorius, Simon's avatar
Praetorius, Simon committed
122 123
    }

124 125 126 127 128 129 130

    template <class GF>
    using HasInsertBoundarySegment = decltype( std::declval<GF>().insertBoundarySegment(
      std::declval<std::vector<unsigned int>>(),
      std::declval<std::shared_ptr<BoundarySegment>>()) );

    /** \brief Insert a shaped boundary segment into the macro grid
Praetorius, Simon's avatar
Praetorius, Simon committed
131
     *
132 133
     *  \param[in]  vertices         Vertex indices of boundary face
     *  \param[in]  boundarySegment  Geometric realization of shaped boundary
Praetorius, Simon's avatar
Praetorius, Simon committed
134
     */
135 136 137
    virtual void insertBoundarySegment (
        const std::vector<unsigned int>& vertices,
        const std::shared_ptr<BoundarySegment>& boundarySegment) override
Praetorius, Simon's avatar
Praetorius, Simon committed
138
    {
139 140 141
      Hybrid::ifElse(Std::is_detected<HasInsertBoundarySegment, GridFactory<HostGrid>>{},
      [&](auto id) {
        for (auto& gridFactory : gridFactories_)
142
          id(gridFactory)->insertBoundarySegment(vertices, boundarySegment);
143
      });
Praetorius, Simon's avatar
Praetorius, Simon committed
144 145 146
    }


147
    /// \brief Finalize grid creation and hand over the grid
Praetorius, Simon's avatar
Praetorius, Simon committed
148 149 150 151
    /**
     * Create n copies of the grid and store it in unique_pointers
     * inside the multimesh grid.
     **/
152
#if DUNE_VERSION_LT(DUNE_GRID,2,7)
Praetorius, Simon's avatar
Praetorius, Simon committed
153 154 155 156
    virtual Grid* createGrid () override
    {
      Grid* multimesh = new Grid{};
      for (auto& gridFactory : gridFactories_)
157
        multimesh->grids_.emplace_back(gridFactory->createGrid());
Praetorius, Simon's avatar
Praetorius, Simon committed
158 159
      return multimesh;
    }
160 161 162
#else
    virtual ToUniquePtr<Grid> createGrid () override
    {
163
      auto multimesh = makeToUnique<Grid>();
164 165 166 167 168
      for (auto& gridFactory : gridFactories_)
        multimesh->grids_.emplace_back(gridFactory->createGrid());
      return std::move(multimesh);
    }
#endif
Praetorius, Simon's avatar
Praetorius, Simon committed
169 170

  private:
171
    std::vector<std::unique_ptr<GridFactory<HostGrid>>> gridFactories_;
Praetorius, Simon's avatar
Praetorius, Simon committed
172 173 174 175
  };

} // end namespace Dune

176
#endif // DUNE_MULTIMESH_GRIDFACTORY_HH