dune-grid  2.8.0
albertagrid/structuredgridfactory.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
5 #define DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
6 
12 #include <array>
13 #include <memory>
14 #include <vector>
15 #include <tuple>
16 
17 #include <dune/common/exceptions.hh>
18 #include <dune/common/fvector.hh>
22 
23 #if HAVE_ALBERTA
24 
25 namespace Dune
26 {
27  // Forward Declarations
28  template <class Grid>
29  class StructuredGridFactory;
30 
31  template <int dim, int dimworld>
32  class AlbertaGrid;
33 
47  template <int dim, int dimworld>
48  class StructuredGridFactory<AlbertaGrid<dim,dimworld>>
49  {
51 
52  protected:
53  using ctype = typename GridType::ctype;
54 
55  // Insert new elements into the grid by splitting the given cube with corners `vertices` into
56  // a curresponding number of simplices.
57  static void insertElement (GridFactory<GridType>& factory,
58  const GeometryType& type,
59  const std::vector<unsigned int>& vertices)
60  {
61  // triangulation of reference cube
62  static const auto reference_cubes = std::make_tuple(
63  /*1d*/ std::array{std::array{0,1}},
64  /*2d*/ std::array{std::array{3,0,1}, std::array{0,3,2}},
65  /*3d*/ std::array{std::array{0,7,3,1}, std::array{0,7,5,1},
66  std::array{0,7,5,4}, std::array{0,7,3,2},
67  std::array{0,7,6,2}, std::array{0,7,6,4}} );
68 
69  const auto& simplices = std::get<dim-1>(reference_cubes);
70  std::vector<unsigned int> corners(dim+1);
71  for (const auto& simplex : simplices) {
72  for (std::size_t i = 0; i < simplex.size(); ++i)
73  corners[i] = vertices[simplex[i]];
74 
75  factory.insertElement(type, corners);
76  }
77  }
78 
79  // Insert a structured set of vertices into the factory
80  static void insertVertices (GridFactory<GridType>& factory,
81  const FieldVector<ctype,dimworld>& lowerLeft,
82  const FieldVector<ctype,dimworld>& upperRight,
83  const std::array<unsigned int,dim>& vertices)
84  {
85  FactoryUtilities::MultiIndex<dim> index(vertices);
86 
87  // Compute the total number of vertices to be created
88  int numVertices = index.cycle();
89 
90  // Create vertices
91  for (int i=0; i<numVertices; i++, ++index) {
92 
93  // scale the multiindex to obtain a world position
94  FieldVector<double,dimworld> pos(0);
95  for (int j=0; j<dim; j++)
96  pos[j] = lowerLeft[j] + index[j] * (upperRight[j]-lowerLeft[j])/(vertices[j]-1);
97  for (int j=dim; j<dimworld; j++)
98  pos[j] = lowerLeft[j];
99 
100  factory.insertVertex(pos);
101 
102  }
103 
104  }
105 
106  // Compute the index offsets needed to move to the adjacent vertices
107  // in the different coordinate directions
108  static std::array<unsigned int, dim> computeUnitOffsets (
109  const std::array<unsigned int,dim>& vertices)
110  {
111  std::array<unsigned int, dim> unitOffsets;
112  if (dim>0) // paranoia
113  unitOffsets[0] = 1;
114 
115  for (int i=1; i<dim; i++)
116  unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
117 
118  return unitOffsets;
119  }
120 
121  public:
133  const FieldVector<ctype,dimworld>& lowerLeft,
134  const FieldVector<ctype,dimworld>& upperRight,
135  const std::array<unsigned int,dim>& elements)
136  {
137  if (factory.comm().rank() == 0)
138  {
139  // Insert uniformly spaced vertices
140  std::array<unsigned int,dim> vertices = elements;
141  for (std::size_t i=0; i<vertices.size(); ++i)
142  vertices[i]++;
143 
144  insertVertices(factory, lowerLeft, upperRight, vertices);
145 
146  // Compute the index offsets needed to move to the adjacent
147  // vertices in the different coordinate directions
148  std::array<unsigned int, dim> unitOffsets =
149  computeUnitOffsets(vertices);
150 
151  // Compute an element template (the cube at (0,...,0). All
152  // other cubes are constructed by moving this template around
153  unsigned int nCorners = 1<<dim;
154 
155  std::vector<unsigned int> cornersTemplate(nCorners,0);
156  for (std::size_t i=0; i<nCorners; ++i)
157  for (int j=0; j<dim; ++j)
158  if ( i & (1<<j) )
159  cornersTemplate[i] += unitOffsets[j];
160 
161  // Insert elements
162  FactoryUtilities::MultiIndex<dim> index(elements);
163 
164  // Compute the total number of elements to be created
165  int numElements = index.cycle();
166 
167  for (int i=0; i<numElements; ++i, ++index) {
168 
169  // 'base' is the index of the lower left element corner
170  unsigned int base = 0;
171  for (int j=0; j<dim; j++)
172  base += index[j] * unitOffsets[j];
173 
174  // insert new element
175  std::vector<unsigned int> corners = cornersTemplate;
176  for (std::size_t j=0; j<corners.size(); ++j)
177  corners[j] += base;
178 
179  insertElement(factory, GeometryTypes::simplex(dim), corners);
180  }
181  }
182  }
183 
193  static std::unique_ptr<GridType> createSimplexGrid (
194  const FieldVector<ctype,dimworld>& lowerLeft,
195  const FieldVector<ctype,dimworld>& upperRight,
196  const std::array<unsigned int,dim>& elements)
197  {
198  GridFactory<GridType> factory;
199  createSimplexGrid(factory, lowerLeft, upperRight, elements);
200  return std::unique_ptr<GridType>(factory.createGrid());
201  }
202 
203 
204  static void createCubeGrid (GridFactory<GridType>& factory,
205  const FieldVector<ctype,dimworld>& lowerLeft,
206  const FieldVector<ctype,dimworld>& upperRight,
207  const std::array<unsigned int,dim>& elements)
208  {
209  DUNE_THROW(Dune::NotImplemented,
210  "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
211  }
212 
213  static std::unique_ptr<GridType> createCubeGrid (
214  const FieldVector<ctype,dimworld>& lowerLeft,
215  const FieldVector<ctype,dimworld>& upperRight,
216  const std::array<unsigned int,dim>& elements)
217  {
218  DUNE_THROW(Dune::NotImplemented,
219  "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
220  return nullptr;
221  }
222  };
223 
224 } // end namespace Dune
225 
226 #endif // HAVE_ALBERTA
227 
228 #endif // DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Include standard header files.
Definition: agrid.hh:58
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:130
[ provides Dune::Grid ]
Definition: agrid.hh:107
GridFamily::ctype ctype
Definition: agrid.hh:141
Construct structured cube and simplex grids in unstructured grid managers.
Definition: utility/structuredgridfactory.hh:29
static void createSimplexGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
insert structured simplex grid into grid factory
Definition: utility/structuredgridfactory.hh:179
static void createCubeGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Definition: albertagrid/structuredgridfactory.hh:204
static std::unique_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Create a structured simplex grid for AlbertaGrid.
Definition: albertagrid/structuredgridfactory.hh:193
static std::unique_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Definition: albertagrid/structuredgridfactory.hh:213
typename GridType::ctype ctype
Definition: albertagrid/structuredgridfactory.hh:53
static void insertVertices(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &vertices)
Definition: albertagrid/structuredgridfactory.hh:80
static void insertElement(GridFactory< GridType > &factory, const GeometryType &type, const std::vector< unsigned int > &vertices)
Definition: albertagrid/structuredgridfactory.hh:57
static std::array< unsigned int, dim > computeUnitOffsets(const std::array< unsigned int, dim > &vertices)
Definition: albertagrid/structuredgridfactory.hh:108
static void createSimplexGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Create a structured simplex grid for AlbertaGrid.
Definition: albertagrid/structuredgridfactory.hh:132
Communication comm() const
Return the Communication used by the grid factory.
Definition: common/gridfactory.hh:295
Provide a generic factory class for unstructured grids.
Definition: common/gridfactory.hh:312
virtual void insertVertex([[maybe_unused]] const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: common/gridfactory.hh:333
virtual void insertElement([[maybe_unused]] const GeometryType &type, [[maybe_unused]] const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: common/gridfactory.hh:344
virtual std::unique_ptr< GridType > createGrid()
Finalize grid creation and hand over the grid.
Definition: common/gridfactory.hh:370
Definition: multiindex.hh:17
size_t cycle() const
Compute how many times you can call operator++ before getting to (0,...,0) again.
Definition: multiindex.hh:46
Provide a generic factory class for unstructured grids.
A class to construct structured cube and simplex grids using the grid factory.