AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
MacroGridFactory.hpp
1 #pragma once
2 
3 #include <dune/common/typeutilities.hh>
4 #include <dune/common/version.hh>
5 #include <dune/grid/utility/structuredgridfactory.hh>
6 
7 #if ! DUNE_VERSION_GT(DUNE_GRID,2,6)
8  #include <dune/grid/yaspgrid.hh>
9 #endif
10 
11 namespace Dune
12 {
13  template <class GridType>
14  struct CubedWrapper : public GridType {};
15 
16 
17  template <class GridType>
18  class GridFactory<CubedWrapper<GridType>>
19  : public GridFactoryInterface<GridType>
20  {
21  using Self = GridFactory;
22  using Super = GridFactoryInterface<GridType>;
23  using ctype = typename GridType::ctype;
24 
25  enum { dim = GridType::dimension };
26  enum { dimworld = GridType::dimensionworld };
27 
28  public:
29  template <class... Args, disableCopyMove<Self, Args...> = 0>
30  GridFactory (Args&&... args)
31  : factory_(std::make_shared<GridFactory<GridType>>(std::forward<Args>(args)...))
32  {}
33 
34  GridFactory (GridFactory<GridType>& factory)
35  : factory_(stackobject_to_shared_ptr(factory))
36  {}
37 
39  void insertVertex (const FieldVector<ctype,dimworld>& pos) override
40  {
41  factory_->insertVertex(pos);
42  }
43 
45 
51  void insertElement (const GeometryType& type,
52  const std::vector<unsigned int>& vertices) override
53  {
54  // triangulation of reference cube
55  static const auto reference_cubes = std::make_tuple(
56  std::array<std::array<int,2>, 1>{std::array<int,2>{0,1}},
57  std::array<std::array<int,3>, 2>{std::array<int,3>{3,0,1}, std::array<int,3>{0,3,2}},
58  std::array<std::array<int,4>, 6>{std::array<int,4>{0,7,3,1}, std::array<int,4>{0,7,5,1},
59  std::array<int,4>{0,7,5,4}, std::array<int,4>{0,7,3,2},
60  std::array<int,4>{0,7,6,2}, std::array<int,4>{0,7,6,4}} );
61 
62  assert(type == GeometryTypes::cube(dim));
63 
64  auto const& simplices = std::get<dim-1>(reference_cubes);
65  thread_local std::vector<unsigned int> corners(dim+1);
66  for (auto const& simplex : simplices) {
67  for (std::size_t i = 0; i < simplex.size(); ++i)
68  corners[i] = vertices[simplex[i]];
69 
70  factory_->insertElement(GeometryTypes::simplex(dim), corners);
71  }
72  }
73 
74  using Super::insertElement;
75 
77  // TODO: maybe split boundary segment in simplices
78  void insertBoundarySegment (const std::vector<unsigned int>& vertices) override
79  {
80  factory_->insertBoundarySegment(vertices);
81  }
82 
83  using Super::insertBoundarySegment;
84 
86 #if DUNE_VERSION_GT(DUNE_GRID,2,6)
87  ToUniquePtr<GridType> createGrid () override
88 #else
89  GridType* createGrid () override
90 #endif
91  {
92  return factory_->createGrid();
93  }
94 
95  private:
96  std::shared_ptr<GridFactory<GridType>> factory_;
97  };
98 
99 } // end namespace Dune
100 
101 
102 namespace AMDiS
103 {
104  template <class GridType>
106  {
107  using ctype = typename GridType::ctype;
108 
109  enum { dim = GridType::dimension };
110  enum { dimworld = GridType::dimensionworld };
111 
112  public:
113 #if DUNE_VERSION_GT(DUNE_GRID,2,6)
114  static std::unique_ptr<GridType> createSimplexGrid (Dune::GridFactory<GridType>& originalFactory,
116  const Dune::FieldVector<ctype,dimworld>& lowerLeft,
117  const Dune::FieldVector<ctype,dimworld>& upperRight,
118  const std::array<unsigned int,dim>& numElements)
119  {
120  Dune::GridFactory<Dune::CubedWrapper<GridType>> factory(originalFactory);
121  Dune::StructuredGridFactory<Dune::CubedWrapper<GridType>>::createCubeGrid(factory, lowerLeft, upperRight, numElements);
122  return std::unique_ptr<GridType>(factory.createGrid());
123  }
124 #endif
125 
127  static std::unique_ptr<GridType> createSimplexGrid (const Dune::FieldVector<ctype,dimworld>& lowerLeft,
128  const Dune::FieldVector<ctype,dimworld>& upperRight,
129  const std::array<unsigned int,dim>& numElements)
130  {
131  Dune::GridFactory<Dune::CubedWrapper<GridType>> factory;
132 #if DUNE_VERSION_GT(DUNE_GRID,2,6)
133  Dune::StructuredGridFactory<Dune::CubedWrapper<GridType>>::createCubeGrid(factory, lowerLeft, upperRight, numElements);
134 #else
135  // fallback implementation using temporary YaspGrid
136  using TempGrid = Dune::YaspGrid<dim,Dune::EquidistantOffsetCoordinates<double,dim>>;
137  auto grid = Dune::StructuredGridFactory<TempGrid>::createCubeGrid(lowerLeft, upperRight, numElements);
138  for (auto const& v : vertices(grid->leafGridView()))
139  factory.insertVertex(v.geometry().corner(0));
140 
141  auto const& indexSet = grid->leafIndexSet();
142  for (auto const& e : elements(grid->leafGridView()))
143  {
144  thread_local std::vector<unsigned int> vertices;
145  vertices.resize(e.subEntities(dim));
146  for (unsigned int i = 0; i < e.subEntities(dim); ++i)
147  vertices[i] = indexSet.subIndex(e,i,dim);
148  factory.insertElement(Dune::GeometryTypes::cube(dim), vertices);
149  }
150 #endif
151  return std::unique_ptr<GridType>(factory.createGrid());
152  }
153  };
154 
155 } // end namespace AMDiS
Definition: AdaptiveGrid.hpp:373
Definition: FieldMatVec.hpp:12
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
static std::unique_ptr< GridType > createSimplexGrid(const Dune::FieldVector< ctype, dimworld > &lowerLeft, const Dune::FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &numElements)
Create a structured simplex grid.
Definition: MacroGridFactory.hpp:127
Definition: MacroGridFactory.hpp:105