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 #ifndef DUNE_STRUCTURED_GRID_FACTORY_HH
6 #define DUNE_STRUCTURED_GRID_FACTORY_HH
7 
12 #include <algorithm>
13 #include <array>
14 #include <cstddef>
15 #include <cstdlib>
16 #include <memory>
17 
18 #include <dune/common/classname.hh>
20 #include <dune/common/fvector.hh>
21 
24 
25 namespace Dune {
26 
29  template <class GridType>
31  {
32  typedef typename GridType::ctype ctype;
33 
34  static const int dim = GridType::dimension;
35 
36  static const int dimworld = GridType::dimensionworld;
37 
39  static void insertVertices(GridFactory<GridType>& factory,
40  const FieldVector<ctype,dimworld>& lowerLeft,
41  const FieldVector<ctype,dimworld>& upperRight,
42  const std::array<unsigned int,dim>& vertices)
43  {
44  FactoryUtilities::MultiIndex<dim> index(vertices);
45 
46  // Compute the total number of vertices to be created
47  int numVertices = index.cycle();
48 
49  // Create vertices
50  for (int i=0; i<numVertices; i++, ++index) {
51 
52  // scale the multiindex to obtain a world position
54  for (int j=0; j<dim; j++)
55  pos[j] = lowerLeft[j] + index[j] * (upperRight[j]-lowerLeft[j])/(vertices[j]-1);
56  for (int j=dim; j<dimworld; j++)
57  pos[j] = lowerLeft[j];
58 
59  factory.insertVertex(pos);
60 
61  }
62 
63  }
64 
65  // Compute the index offsets needed to move to the adjacent vertices
66  // in the different coordinate directions
67  static std::array<unsigned int, dim> computeUnitOffsets(const std::array<unsigned int,dim>& vertices)
68  {
69  std::array<unsigned int, dim> unitOffsets;
70  if (dim>0) // paranoia
71  unitOffsets[0] = 1;
72 
73  for (int i=1; i<dim; i++)
74  unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
75 
76  return unitOffsets;
77  }
78 
79  public:
80 
91  static void createCubeGrid(
92  GridFactory<GridType>& factory,
93  const FieldVector<ctype,dimworld>& lowerLeft,
94  const FieldVector<ctype,dimworld>& upperRight,
95  const std::array<unsigned int,dim>& elements)
96  {
97  if (factory.comm().rank() == 0)
98  {
99  // Insert uniformly spaced vertices
100  std::array<unsigned int,dim> vertices = elements;
101  for( size_t i = 0; i < vertices.size(); ++i )
102  vertices[i]++;
103 
104  // Insert vertices for structured grid into the factory
105  insertVertices(factory, lowerLeft, upperRight, vertices);
106 
107  // Compute the index offsets needed to move to the adjacent
108  // vertices in the different coordinate directions
109  std::array<unsigned int, dim> unitOffsets =
110  computeUnitOffsets(vertices);
111 
112  // Compute an element template (the cube at (0,...,0). All
113  // other cubes are constructed by moving this template around
114  unsigned int nCorners = 1<<dim;
115 
116  std::vector<unsigned int> cornersTemplate(nCorners,0);
117 
118  for (size_t i=0; i<nCorners; i++)
119  for (int j=0; j<dim; j++)
120  if ( i & (1<<j) )
121  cornersTemplate[i] += unitOffsets[j];
122 
123  // Insert elements
124  FactoryUtilities::MultiIndex<dim> index(elements);
125 
126  // Compute the total number of elementss to be created
127  int numElements = index.cycle();
128 
129  for (int i=0; i<numElements; i++, ++index) {
130 
131  // 'base' is the index of the lower left element corner
132  unsigned int base = 0;
133  for (int j=0; j<dim; j++)
134  base += index[j] * unitOffsets[j];
135 
136  // insert new element
137  std::vector<unsigned int> corners = cornersTemplate;
138  for (size_t j=0; j<corners.size(); j++)
139  corners[j] += base;
140 
141  factory.insertElement(GeometryTypes::cube(dim), corners);
142 
143  }
144 
145  } // if(rank == 0)
146  }
147 
157  static std::unique_ptr<GridType> createCubeGrid(
158  const FieldVector<ctype,dimworld>& lowerLeft,
159  const FieldVector<ctype,dimworld>& upperRight,
160  const std::array<unsigned int,dim>& elements)
161  {
162  GridFactory<GridType> factory;
163  createCubeGrid(factory, lowerLeft, upperRight, elements);
164  return std::unique_ptr<GridType>(factory.createGrid());
165  }
166 
181  static void createSimplexGrid(
182  GridFactory<GridType>& factory,
183  const FieldVector<ctype,dimworld>& lowerLeft,
184  const FieldVector<ctype,dimworld>& upperRight,
185  const std::array<unsigned int,dim>& elements)
186  {
187  if(factory.comm().rank() == 0)
188  {
189  // Insert uniformly spaced vertices
190  std::array<unsigned int,dim> vertices = elements;
191  for (std::size_t i=0; i<vertices.size(); i++)
192  vertices[i]++;
193 
194  insertVertices(factory, lowerLeft, upperRight, vertices);
195 
196  // Compute the index offsets needed to move to the adjacent
197  // vertices in the different coordinate directions
198  std::array<unsigned int, dim> unitOffsets =
199  computeUnitOffsets(vertices);
200 
201  // Loop over all "cubes", and split up each cube into dim!
202  // (factorial) simplices
203  FactoryUtilities::MultiIndex<dim> elementsIndex(elements);
204  size_t cycle = elementsIndex.cycle();
205 
206  for (size_t i=0; i<cycle; ++elementsIndex, i++) {
207 
208  // 'base' is the index of the lower left element corner
209  unsigned int base = 0;
210  for (int j=0; j<dim; j++)
211  base += elementsIndex[j] * unitOffsets[j];
212 
213  // each permutation of the unit vectors gives a simplex.
214  std::vector<unsigned int> permutation(dim);
215  for (int j=0; j<dim; j++)
216  permutation[j] = j;
217 
218  do {
219 
220  // Make a simplex
221  std::vector<unsigned int> corners(dim+1);
222  corners[0] = base;
223 
224  for (int j=0; j<dim; j++)
225  corners[j+1] =
226  corners[j] + unitOffsets[permutation[j]];
227 
228  factory.insertElement(GeometryTypes::simplex(dim), corners);
229 
230  } while (std::next_permutation(permutation.begin(),
231  permutation.end()));
232 
233  }
234 
235  } // if(rank == 0)
236  }
237 
251  static std::unique_ptr<GridType> createSimplexGrid(
252  const FieldVector<ctype,dimworld>& lowerLeft,
253  const FieldVector<ctype,dimworld>& upperRight,
254  const std::array<unsigned int,dim>& elements)
255  {
256  GridFactory<GridType> factory;
257  createSimplexGrid(factory, lowerLeft, upperRight, elements);
258  return std::unique_ptr<GridType>(factory.createGrid());
259  }
260 
261  };
262 
263 } // namespace Dune
264 
265 #endif
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
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
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structuredgridfactory.hh:31
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.
Definition: structuredgridfactory.hh:251
static std::unique_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Create a structured cube grid.
Definition: structuredgridfactory.hh:157
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
A free function to provide the demangled class name of a given object or type as a string.
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.
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:462
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 1, 22:29, 2024)