Dune Core Modules (2.7.1)

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