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 
16 #include <dune/common/classname.hh>
18 #include <dune/common/fvector.hh>
20 
23 
24 namespace 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
94  GridFactory<GridType> 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 void insertVertex(const FieldVector< ctype, dimworld > &pos)
Insert a vertex into the coarse grid.
Definition: gridfactory.hh:279
virtual GridType * createGrid()
Finalize grid creation and hand over the grid.
Definition: gridfactory.hh:316
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structuredgridfactory.hh:30
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
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
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.80.0 (Apr 24, 22:30, 2024)