Dune Core Modules (2.4.2)

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 <cstddef>
12 #include <cstdlib>
13 
14 #include <dune/common/array.hh>
15 #include <dune/common/classname.hh>
17 #include <dune/common/fvector.hh>
20 
23 #include <dune/grid/yaspgrid.hh>
24 
25 namespace 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 array<unsigned int,dim>& vertices)
43  {
44  FactoryUtilities::MultiIndex<dim> index(vertices);
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
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 array<unsigned int, dim> computeUnitOffsets(const array<unsigned int,dim>& vertices)
68  {
69  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 
90  static shared_ptr<GridType> createCubeGrid(const FieldVector<ctype,dimworld>& lowerLeft,
91  const FieldVector<ctype,dimworld>& upperRight,
92  const array<unsigned int,dim>& elements)
93  {
94  // The grid factory
95  GridFactory<GridType> factory;
96 
97  if (MPIHelper::getCollectiveCommunication().rank() == 0)
98  {
99  // Insert uniformly spaced vertices
100  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  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
142  (GeometryType(GeometryType::cube, dim), corners);
143 
144  }
145 
146  } // if(rank == 0)
147 
148  // Create the grid and hand it to the calling method
149  return shared_ptr<GridType>(factory.createGrid());
150 
151  }
152 
166  static shared_ptr<GridType> createSimplexGrid(const FieldVector<ctype,dimworld>& lowerLeft,
167  const FieldVector<ctype,dimworld>& upperRight,
168  const array<unsigned int,dim>& elements)
169  {
170  // The grid factory
171  GridFactory<GridType> factory;
172 
173  if(MPIHelper::getCollectiveCommunication().rank() == 0)
174  {
175  // Insert uniformly spaced vertices
176  array<unsigned int,dim> vertices = elements;
177  for (std::size_t i=0; i<vertices.size(); i++)
178  vertices[i]++;
179 
180  insertVertices(factory, lowerLeft, upperRight, vertices);
181 
182  // Compute the index offsets needed to move to the adjacent
183  // vertices in the different coordinate directions
184  array<unsigned int, dim> unitOffsets =
185  computeUnitOffsets(vertices);
186 
187  // Insert the elements
188  std::vector<unsigned int> corners(dim+1);
189 
190  // Loop over all "cubes", and split up each cube into dim!
191  // (factorial) simplices
192  FactoryUtilities::MultiIndex<dim> elementsIndex(elements);
193  size_t cycle = elementsIndex.cycle();
194 
195  for (size_t i=0; i<cycle; ++elementsIndex, i++) {
196 
197  // 'base' is the index of the lower left element corner
198  unsigned int base = 0;
199  for (int j=0; j<dim; j++)
200  base += elementsIndex[j] * unitOffsets[j];
201 
202  // each permutation of the unit vectors gives a simplex.
203  std::vector<unsigned int> permutation(dim);
204  for (int j=0; j<dim; j++)
205  permutation[j] = j;
206 
207  do {
208 
209  // Make a simplex
210  std::vector<unsigned int> corners(dim+1);
211  corners[0] = base;
212 
213  for (int j=0; j<dim; j++)
214  corners[j+1] =
215  corners[j] + unitOffsets[permutation[j]];
216 
217  factory.insertElement
219  corners);
220 
221  } while (std::next_permutation(permutation.begin(),
222  permutation.end()));
223 
224  }
225 
226  } // if(rank == 0)
227 
228  // Create the grid and hand it to the calling method
229  return shared_ptr<GridType>(factory.createGrid());
230  }
231 
232  };
233 
243  template<class ctype, int dim>
246  static const int dimworld = GridType::dimensionworld;
247 
248  public:
259  static shared_ptr<GridType>
261  const FieldVector<ctype,dimworld>& upperRight,
262  const array<unsigned int,dim>& elements)
263  {
264  using std::abs;
265  for(int d = 0; d < dimworld; ++d)
266  if(abs(lowerLeft[d]) > abs(upperRight[d])*1e-10)
267  DUNE_THROW(GridError, className<StructuredGridFactory>()
268  << "::createCubeGrid(): You have to use Yaspgrid<dim"
269  ", EquidistantOffsetCoordinates<ctype,dim> > as your"
270  "grid type for non-trivial origin." );
271 
272  // construct array of ints instead of unsigned ints
273  array<int, dim> elem;
274  std::copy(elements.begin(), elements.end(), elem.begin());
275 
276  return shared_ptr<GridType>
277  (new GridType(upperRight, elem,
278  std::bitset<dim>(), 0)); // default constructor of bitset sets to zero
279  }
280 
286  static shared_ptr<GridType>
288  const FieldVector<ctype,dimworld>& upperRight,
289  const array<unsigned int,dim>& elements)
290  {
291  DUNE_THROW(GridError, className<StructuredGridFactory>()
292  << "::createSimplexGrid(): Simplices are not supported "
293  "by YaspGrid.");
294  }
295 
296  };
297 
307  template<class ctype, int dim>
310  static const int dimworld = GridType::dimensionworld;
311 
312  public:
319  static shared_ptr<GridType>
321  const FieldVector<ctype,dimworld>& upperRight,
322  const array<unsigned int,dim>& elements)
323  {
324  // construct array of ints instead of unsigned ints
325  array<int, dim> elem;
326  std::copy(elements.begin(), elements.end(), elem.begin());
327 
328  return shared_ptr<GridType>
329  (new GridType(lowerLeft, upperRight, elem,
330  std::bitset<dim>(), 0)); // default constructor of bitset sets to zero
331  }
332 
338  static shared_ptr<GridType>
340  const FieldVector<ctype,dimworld>& upperRight,
341  const array<unsigned int,dim>& elements)
342  {
343  DUNE_THROW(GridError, className<StructuredGridFactory>()
344  << "::createSimplexGrid(): Simplices are not supported "
345  "by YaspGrid.");
346  }
347 
348  };
349 
350 } // namespace Dune
351 
352 #endif
Fallback implementation of the std::array class (a static array)
Container for equidistant coordinates in a YaspGrid.
Definition: coordinates.hh:27
Container for equidistant coordinates in a YaspGrid with non-trivial origin.
Definition: coordinates.hh:125
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:25
@ cube
Cube element in any nonnegative dimension.
Definition: type.hh:31
@ simplex
Simplicial element in any nonnegative dimension.
Definition: type.hh:30
Base class for exceptions in Dune grid modules.
Definition: exceptions.hh:18
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
static shared_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured cube grid.
Definition: structuredgridfactory.hh:260
static shared_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured simplex grid.
Definition: structuredgridfactory.hh:287
static shared_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured simplex grid.
Definition: structuredgridfactory.hh:339
static shared_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured cube grid.
Definition: structuredgridfactory.hh:320
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structuredgridfactory.hh:31
static shared_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured simplex grid.
Definition: structuredgridfactory.hh:166
static shared_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< unsigned int, dim > &elements)
Create a structured cube grid.
Definition: structuredgridfactory.hh:90
[ provides Dune::Grid ]
Definition: yaspgrid.hh:166
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.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
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:10
This file implements the class shared_ptr (a reference counting pointer), for those systems that don'...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)