mmgridfactory.hh 5.26 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>
Praetorius, Simon's avatar
Praetorius, Simon committed
7
#include <type_traits>
Praetorius, Simon's avatar
Praetorius, Simon committed
8 9
#include <vector>

Praetorius, Simon's avatar
Praetorius, Simon committed
10 11
#include <dune/common/hybridutilities.hh>
#include <dune/common/std/type_traits.hh>
Praetorius, Simon's avatar
Praetorius, Simon committed
12 13 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
#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>;
Praetorius, Simon's avatar
Praetorius, Simon committed
42
    using ElementParametrization = VirtualFunction<LocalCoordinate, GlobalCoordinate>;
Praetorius, Simon's avatar
Praetorius, Simon committed
43 44 45 46 47

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

58 59 60 61 62
    // initialize at least 1 grid
    GridFactory ()
      : GridFactory{1}
    {}

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
85 86 87 88 89 90 91

    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
92 93
    /// \brief Insert a parametrized element into the coarse grid
    /**
Praetorius, Simon's avatar
Praetorius, Simon committed
94 95 96
     *   \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
97
     **/
Praetorius, Simon's avatar
Praetorius, Simon committed
98 99 100 101 102 103 104 105
    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_)
106
          id(gridFactory)->insertElement(type, vertices, param);
Praetorius, Simon's avatar
Praetorius, Simon committed
107 108 109 110
      });
    }

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

Praetorius, Simon's avatar
Praetorius, Simon committed
122 123 124 125 126 127 128

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


Praetorius, Simon's avatar
Praetorius, Simon committed
145
    /// \brief Finalize grid creation and hand over the grid
Praetorius, Simon's avatar
Praetorius, Simon committed
146 147 148 149 150 151 152 153
    /**
     * 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_)
154
        multimesh->grids_.emplace_back(gridFactory->createGrid());
Praetorius, Simon's avatar
Praetorius, Simon committed
155 156 157 158
      return multimesh;
    }

  private:
159
    std::vector<std::unique_ptr<GridFactory<HostGrid>>> gridFactories_;
Praetorius, Simon's avatar
Praetorius, Simon committed
160 161 162 163
  };

} // end namespace Dune

164
#endif // DUNE_MULTIMESH_GRIDFACTORY_HH