Dune Core Modules (2.6.0)

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
20
23
24namespace Dune {
25
28 template <class GridType>
30 {
31 typedef typename GridType::ctype ctype;
32
33 static const int dim = GridType::dimension;
34
35 static const int dimworld = GridType::dimensionworld;
36
38 static void insertVertices(GridFactory<GridType>& factory,
39 const FieldVector<ctype,dimworld>& lowerLeft,
40 const FieldVector<ctype,dimworld>& upperRight,
41 const std::array<unsigned int,dim>& vertices)
42 {
43 FactoryUtilities::MultiIndex<dim> index(vertices);
44
45 // Compute the total number of vertices to be created
46 int numVertices = index.cycle();
47
48 // Create vertices
49 for (int i=0; i<numVertices; i++, ++index) {
50
51 // scale the multiindex to obtain a world position
53 for (int j=0; j<dim; j++)
54 pos[j] = lowerLeft[j] + index[j] * (upperRight[j]-lowerLeft[j])/(vertices[j]-1);
55 for (int j=dim; j<dimworld; j++)
56 pos[j] = lowerLeft[j];
57
58 factory.insertVertex(pos);
59
60 }
61
62 }
63
64 // Compute the index offsets needed to move to the adjacent vertices
65 // in the different coordinate directions
66 static std::array<unsigned int, dim> computeUnitOffsets(const std::array<unsigned int,dim>& vertices)
67 {
68 std::array<unsigned int, dim> unitOffsets;
69 if (dim>0) // paranoia
70 unitOffsets[0] = 1;
71
72 for (int i=1; i<dim; i++)
73 unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
74
75 return unitOffsets;
76 }
77
78 public:
79
89 static std::unique_ptr<GridType> createCubeGrid(const FieldVector<ctype,dimworld>& lowerLeft,
90 const FieldVector<ctype,dimworld>& upperRight,
91 const std::array<unsigned int,dim>& elements)
92 {
93 // The grid factory
95
96 if (MPIHelper::getCollectiveCommunication().rank() == 0)
97 {
98 // Insert uniformly spaced vertices
99 std::array<unsigned int,dim> vertices = elements;
100 for( size_t i = 0; i < vertices.size(); ++i )
101 vertices[i]++;
102
103 // Insert vertices for structured grid into the factory
104 insertVertices(factory, lowerLeft, upperRight, vertices);
105
106 // Compute the index offsets needed to move to the adjacent
107 // vertices in the different coordinate directions
108 std::array<unsigned int, dim> unitOffsets =
109 computeUnitOffsets(vertices);
110
111 // Compute an element template (the cube at (0,...,0). All
112 // other cubes are constructed by moving this template around
113 unsigned int nCorners = 1<<dim;
114
115 std::vector<unsigned int> cornersTemplate(nCorners,0);
116
117 for (size_t i=0; i<nCorners; i++)
118 for (int j=0; j<dim; j++)
119 if ( i & (1<<j) )
120 cornersTemplate[i] += unitOffsets[j];
121
122 // Insert elements
123 FactoryUtilities::MultiIndex<dim> index(elements);
124
125 // Compute the total number of elementss to be created
126 int numElements = index.cycle();
127
128 for (int i=0; i<numElements; i++, ++index) {
129
130 // 'base' is the index of the lower left element corner
131 unsigned int base = 0;
132 for (int j=0; j<dim; j++)
133 base += index[j] * unitOffsets[j];
134
135 // insert new element
136 std::vector<unsigned int> corners = cornersTemplate;
137 for (size_t j=0; j<corners.size(); j++)
138 corners[j] += base;
139
140 factory.insertElement(GeometryTypes::cube(dim), corners);
141
142 }
143
144 } // if(rank == 0)
145
146 // Create the grid and hand it to the calling method
147 return std::unique_ptr<GridType>(factory.createGrid());
148
149 }
150
164 static std::unique_ptr<GridType> createSimplexGrid(const FieldVector<ctype,dimworld>& lowerLeft,
165 const FieldVector<ctype,dimworld>& upperRight,
166 const std::array<unsigned int,dim>& elements)
167 {
168 // The grid factory
169 GridFactory<GridType> factory;
170
171 if(MPIHelper::getCollectiveCommunication().rank() == 0)
172 {
173 // Insert uniformly spaced vertices
174 std::array<unsigned int,dim> vertices = elements;
175 for (std::size_t i=0; i<vertices.size(); i++)
176 vertices[i]++;
177
178 insertVertices(factory, lowerLeft, upperRight, vertices);
179
180 // Compute the index offsets needed to move to the adjacent
181 // vertices in the different coordinate directions
182 std::array<unsigned int, dim> unitOffsets =
183 computeUnitOffsets(vertices);
184
185 // Loop over all "cubes", and split up each cube into dim!
186 // (factorial) simplices
187 FactoryUtilities::MultiIndex<dim> elementsIndex(elements);
188 size_t cycle = elementsIndex.cycle();
189
190 for (size_t i=0; i<cycle; ++elementsIndex, i++) {
191
192 // 'base' is the index of the lower left element corner
193 unsigned int base = 0;
194 for (int j=0; j<dim; j++)
195 base += elementsIndex[j] * unitOffsets[j];
196
197 // each permutation of the unit vectors gives a simplex.
198 std::vector<unsigned int> permutation(dim);
199 for (int j=0; j<dim; j++)
200 permutation[j] = j;
201
202 do {
203
204 // Make a simplex
205 std::vector<unsigned int> corners(dim+1);
206 corners[0] = base;
207
208 for (int j=0; j<dim; j++)
209 corners[j+1] =
210 corners[j] + unitOffsets[permutation[j]];
211
212 factory.insertElement(GeometryTypes::simplex(dim), corners);
213
214 } while (std::next_permutation(permutation.begin(),
215 permutation.end()));
216
217 }
218
219 } // if(rank == 0)
220
221 // Create the grid and hand it to the calling method
222 return std::unique_ptr<GridType>(factory.createGrid());
223 }
224
225 };
226
227} // namespace Dune
228
229#endif
Provide a generic factory class for unstructured grids.
Definition: gridfactory.hh:263
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: gridfactory.hh:290
virtual GridType * createGrid()
Finalize grid creation and hand over the grid.
Definition: gridfactory.hh:316
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: gridfactory.hh:279
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structuredgridfactory.hh:30
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:89
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:164
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:705
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:696
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)