Dune Core Modules (2.5.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::shared_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
141  (GeometryType(GeometryType::cube, dim), corners);
142 
143  }
144 
145  } // if(rank == 0)
146 
147  // Create the grid and hand it to the calling method
148  return std::shared_ptr<GridType>(factory.createGrid());
149 
150  }
151 
165  static std::shared_ptr<GridType> createSimplexGrid(const FieldVector<ctype,dimworld>& lowerLeft,
166  const FieldVector<ctype,dimworld>& upperRight,
167  const std::array<unsigned int,dim>& elements)
168  {
169  // The grid factory
170  GridFactory<GridType> factory;
171 
172  if(MPIHelper::getCollectiveCommunication().rank() == 0)
173  {
174  // Insert uniformly spaced vertices
175  std::array<unsigned int,dim> vertices = elements;
176  for (std::size_t i=0; i<vertices.size(); i++)
177  vertices[i]++;
178 
179  insertVertices(factory, lowerLeft, upperRight, vertices);
180 
181  // Compute the index offsets needed to move to the adjacent
182  // vertices in the different coordinate directions
183  std::array<unsigned int, dim> unitOffsets =
184  computeUnitOffsets(vertices);
185 
186  // Loop over all "cubes", and split up each cube into dim!
187  // (factorial) simplices
188  FactoryUtilities::MultiIndex<dim> elementsIndex(elements);
189  size_t cycle = elementsIndex.cycle();
190 
191  for (size_t i=0; i<cycle; ++elementsIndex, i++) {
192 
193  // 'base' is the index of the lower left element corner
194  unsigned int base = 0;
195  for (int j=0; j<dim; j++)
196  base += elementsIndex[j] * unitOffsets[j];
197 
198  // each permutation of the unit vectors gives a simplex.
199  std::vector<unsigned int> permutation(dim);
200  for (int j=0; j<dim; j++)
201  permutation[j] = j;
202 
203  do {
204 
205  // Make a simplex
206  std::vector<unsigned int> corners(dim+1);
207  corners[0] = base;
208 
209  for (int j=0; j<dim; j++)
210  corners[j+1] =
211  corners[j] + unitOffsets[permutation[j]];
212 
213  factory.insertElement
215  corners);
216 
217  } while (std::next_permutation(permutation.begin(),
218  permutation.end()));
219 
220  }
221 
222  } // if(rank == 0)
223 
224  // Create the grid and hand it to the calling method
225  return std::shared_ptr<GridType>(factory.createGrid());
226  }
227 
228  };
229 
230 } // namespace Dune
231 
232 #endif
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:268
@ cube
Cube element in any nonnegative dimension.
Definition: type.hh:274
@ simplex
Simplicial element in any nonnegative dimension.
Definition: type.hh:273
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::shared_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::shared_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:165
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 vector constructed from a given type representing a field and a compile-time given size.
Helpers for dealing with MPI.
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Dune namespace.
Definition: alignment.hh:11
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)