dune-grid 2.9.0
utility/structuredgridfactory.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) 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>
19#include <dune/common/exceptions.hh>
20#include <dune/common/fvector.hh>
21
24
25namespace 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 {
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
53 FieldVector<double,dimworld> pos(0);
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
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Include standard header files.
Definition: agrid.hh:60
Construct structured cube and simplex grids in unstructured grid managers.
Definition: utility/structuredgridfactory.hh:31
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: utility/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: utility/structuredgridfactory.hh:181
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: utility/structuredgridfactory.hh:251
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: utility/structuredgridfactory.hh:91
Communication comm() const
Return the Communication used by the grid factory.
Definition: common/gridfactory.hh:297
Provide a generic factory class for unstructured grids.
Definition: common/gridfactory.hh:314
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
Insert an element into the coarse grid.
Definition: common/gridfactory.hh:346
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: common/gridfactory.hh:335
virtual std::unique_ptr< GridType > createGrid()
Finalize grid creation and hand over the grid.
Definition: common/gridfactory.hh:372
Definition: multiindex.hh:19
size_t cycle() const
Compute how many times you can call operator++ before getting to (0,...,0) again.
Definition: multiindex.hh:48
Provide a generic factory class for unstructured grids.