Dune Core Modules (unstable)

structuredgridfactory.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 
6 #ifndef DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
7 #define DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
8 
14 #include <array>
15 #include <memory>
16 #include <vector>
17 #include <tuple>
18 
20 #include <dune/common/fvector.hh>
24 
25 #if HAVE_ALBERTA
26 
27 namespace Dune
28 {
29  // Forward Declarations
30  template <class Grid>
31  class StructuredGridFactory;
32 
33  template <int dim, int dimworld>
34  class AlbertaGrid;
35 
49  template <int dim, int dimworld>
50  class StructuredGridFactory<AlbertaGrid<dim,dimworld>>
51  {
53 
54  protected:
55  using ctype = typename GridType::ctype;
56 
57  // Insert new elements into the grid by splitting the given cube with corners `vertices` into
58  // a corresponding number of simplices.
59  static void insertElement (GridFactory<GridType>& factory,
60  const GeometryType& type,
61  const std::vector<unsigned int>& vertices)
62  {
63  // triangulation of reference cube
64  static const auto reference_cubes = std::make_tuple(
65  /*1d*/ std::array<std::array<int,2>,1>{
66  std::array<int,2>{0,1}},
67  /*2d*/ std::array<std::array<int,3>,2>{
68  std::array<int,3>{3,0,1}, std::array<int,3>{0,3,2}},
69  /*3d*/ std::array<std::array<int,4>,6>{
70  std::array<int,4>{0,7,3,1}, std::array<int,4>{0,7,5,1},
71  std::array<int,4>{0,7,5,4}, std::array<int,4>{0,7,3,2},
72  std::array<int,4>{0,7,6,2}, std::array<int,4>{0,7,6,4}} );
73 
74  const auto& simplices = std::get<dim-1>(reference_cubes);
75  std::vector<unsigned int> corners(dim+1);
76  for (const auto& simplex : simplices) {
77  for (std::size_t i = 0; i < simplex.size(); ++i)
78  corners[i] = vertices[simplex[i]];
79 
80  factory.insertElement(type, corners);
81  }
82  }
83 
84  // Insert a structured set of vertices into the factory
85  static void insertVertices (GridFactory<GridType>& factory,
86  const FieldVector<ctype,dimworld>& lowerLeft,
87  const FieldVector<ctype,dimworld>& upperRight,
88  const std::array<unsigned int,dim>& vertices)
89  {
90  FactoryUtilities::MultiIndex<dim> index(vertices);
91 
92  // Compute the total number of vertices to be created
93  int numVertices = index.cycle();
94 
95  // Create vertices
96  for (int i=0; i<numVertices; i++, ++index) {
97 
98  // scale the multiindex to obtain a world position
100  for (int j=0; j<dim; j++)
101  pos[j] = lowerLeft[j] + index[j] * (upperRight[j]-lowerLeft[j])/(vertices[j]-1);
102  for (int j=dim; j<dimworld; j++)
103  pos[j] = lowerLeft[j];
104 
105  factory.insertVertex(pos);
106 
107  }
108 
109  }
110 
111  // Compute the index offsets needed to move to the adjacent vertices
112  // in the different coordinate directions
113  static std::array<unsigned int, dim> computeUnitOffsets (
114  const std::array<unsigned int,dim>& vertices)
115  {
116  std::array<unsigned int, dim> unitOffsets;
117  if (dim>0) // paranoia
118  unitOffsets[0] = 1;
119 
120  for (int i=1; i<dim; i++)
121  unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
122 
123  return unitOffsets;
124  }
125 
126  public:
138  const FieldVector<ctype,dimworld>& lowerLeft,
139  const FieldVector<ctype,dimworld>& upperRight,
140  const std::array<unsigned int,dim>& elements)
141  {
142  if (factory.comm().rank() == 0)
143  {
144  // Insert uniformly spaced vertices
145  std::array<unsigned int,dim> vertices = elements;
146  for (std::size_t i=0; i<vertices.size(); ++i)
147  vertices[i]++;
148 
149  insertVertices(factory, lowerLeft, upperRight, vertices);
150 
151  // Compute the index offsets needed to move to the adjacent
152  // vertices in the different coordinate directions
153  std::array<unsigned int, dim> unitOffsets =
154  computeUnitOffsets(vertices);
155 
156  // Compute an element template (the cube at (0,...,0). All
157  // other cubes are constructed by moving this template around
158  unsigned int nCorners = 1<<dim;
159 
160  std::vector<unsigned int> cornersTemplate(nCorners,0);
161  for (std::size_t i=0; i<nCorners; ++i)
162  for (int j=0; j<dim; ++j)
163  if ( i & (1<<j) )
164  cornersTemplate[i] += unitOffsets[j];
165 
166  // Insert elements
167  FactoryUtilities::MultiIndex<dim> index(elements);
168 
169  // Compute the total number of elements to be created
170  int numElements = index.cycle();
171 
172  for (int i=0; i<numElements; ++i, ++index) {
173 
174  // 'base' is the index of the lower left element corner
175  unsigned int base = 0;
176  for (int j=0; j<dim; j++)
177  base += index[j] * unitOffsets[j];
178 
179  // insert new element
180  std::vector<unsigned int> corners = cornersTemplate;
181  for (std::size_t j=0; j<corners.size(); ++j)
182  corners[j] += base;
183 
184  insertElement(factory, GeometryTypes::simplex(dim), corners);
185  }
186  }
187  }
188 
198  static std::unique_ptr<GridType> createSimplexGrid (
199  const FieldVector<ctype,dimworld>& lowerLeft,
200  const FieldVector<ctype,dimworld>& upperRight,
201  const std::array<unsigned int,dim>& elements)
202  {
203  GridFactory<GridType> factory;
204  createSimplexGrid(factory, lowerLeft, upperRight, elements);
205  return std::unique_ptr<GridType>(factory.createGrid());
206  }
207 
208 
209  static void createCubeGrid (GridFactory<GridType>& factory,
210  const FieldVector<ctype,dimworld>& lowerLeft,
211  const FieldVector<ctype,dimworld>& upperRight,
212  const std::array<unsigned int,dim>& elements)
213  {
215  "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
216  }
217 
218  static std::unique_ptr<GridType> createCubeGrid (
219  const FieldVector<ctype,dimworld>& lowerLeft,
220  const FieldVector<ctype,dimworld>& upperRight,
221  const std::array<unsigned int,dim>& elements)
222  {
224  "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
225  return nullptr;
226  }
227  };
228 
229 } // end namespace Dune
230 
231 #endif // HAVE_ALBERTA
232 
233 #endif // DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
[ provides Dune::Grid ]
Definition: agrid.hh:109
int rank() const
Return rank, is between 0 and size()-1.
Definition: communication.hh:114
vector space out of a tensor product of fields.
Definition: fvector.hh:95
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
Communication comm() const
Return the Communication used by the grid factory.
Definition: gridfactory.hh:258
Provide a generic factory class for unstructured grids.
Definition: gridfactory.hh:275
virtual void insertVertex([[maybe_unused]] const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: gridfactory.hh:296
virtual void insertElement([[maybe_unused]] const GeometryType &type, [[maybe_unused]] const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: gridfactory.hh:307
virtual std::unique_ptr< GridType > createGrid()
Finalize grid creation and hand over the grid.
Definition: gridfactory.hh:333
Default exception for dummy implementations.
Definition: exceptions.hh:263
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: structuredgridfactory.hh:198
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: structuredgridfactory.hh:137
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structuredgridfactory.hh:31
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: structuredgridfactory.hh:181
static void createCubeGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
insert structured cube grid into grid factory
Definition: structuredgridfactory.hh:91
Provide a generic factory class for unstructured grids.
A few common exception classes.
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:453
Dune namespace.
Definition: alignedallocator.hh:13
A class to construct structured cube and simplex grids using the grid factory.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 26, 22:29, 2024)