dune-grid 2.9.0
albertagrid/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
6#ifndef DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
7#define DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
8
14#include <array>
15#include <memory>
16#include <vector>
17#include <tuple>
18
19#include <dune/common/exceptions.hh>
20#include <dune/common/fvector.hh>
24
25#if HAVE_ALBERTA
26
27namespace Dune
28{
29 // Forward Declarations
30 template <class Grid>
31 class StructuredGridFactory;
32
33 template <int dim, int dimworld>
34 class AlbertaGrid;
35
49 template <int dim, int dimworld>
51 {
53
54 protected:
55 using ctype = typename GridType::ctype;
56
57 // Insert new elements into the grid by splitting the given cube with corners `vertices` into
58 // a curresponding number of simplices.
59 static void insertElement (GridFactory<GridType>& factory,
60 const GeometryType& type,
61 const std::vector<unsigned int>& vertices)
62 {
63 // triangulation of reference cube
64 static const auto reference_cubes = std::make_tuple(
65 /*1d*/ std::array{std::array{0,1}},
66 /*2d*/ std::array{std::array{3,0,1}, std::array{0,3,2}},
67 /*3d*/ std::array{std::array{0,7,3,1}, std::array{0,7,5,1},
68 std::array{0,7,5,4}, std::array{0,7,3,2},
69 std::array{0,7,6,2}, std::array{0,7,6,4}} );
70
71 const auto& simplices = std::get<dim-1>(reference_cubes);
72 std::vector<unsigned int> corners(dim+1);
73 for (const auto& simplex : simplices) {
74 for (std::size_t i = 0; i < simplex.size(); ++i)
75 corners[i] = vertices[simplex[i]];
76
77 factory.insertElement(type, corners);
78 }
79 }
80
81 // Insert a structured set of vertices into the factory
83 const FieldVector<ctype,dimworld>& lowerLeft,
84 const FieldVector<ctype,dimworld>& upperRight,
85 const std::array<unsigned int,dim>& vertices)
86 {
88
89 // Compute the total number of vertices to be created
90 int numVertices = index.cycle();
91
92 // Create vertices
93 for (int i=0; i<numVertices; i++, ++index) {
94
95 // scale the multiindex to obtain a world position
96 FieldVector<double,dimworld> pos(0);
97 for (int j=0; j<dim; j++)
98 pos[j] = lowerLeft[j] + index[j] * (upperRight[j]-lowerLeft[j])/(vertices[j]-1);
99 for (int j=dim; j<dimworld; j++)
100 pos[j] = lowerLeft[j];
101
102 factory.insertVertex(pos);
103
104 }
105
106 }
107
108 // Compute the index offsets needed to move to the adjacent vertices
109 // in the different coordinate directions
110 static std::array<unsigned int, dim> computeUnitOffsets (
111 const std::array<unsigned int,dim>& vertices)
112 {
113 std::array<unsigned int, dim> unitOffsets;
114 if (dim>0) // paranoia
115 unitOffsets[0] = 1;
116
117 for (int i=1; i<dim; i++)
118 unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
119
120 return unitOffsets;
121 }
122
123 public:
135 const FieldVector<ctype,dimworld>& lowerLeft,
136 const FieldVector<ctype,dimworld>& upperRight,
137 const std::array<unsigned int,dim>& elements)
138 {
139 if (factory.comm().rank() == 0)
140 {
141 // Insert uniformly spaced vertices
142 std::array<unsigned int,dim> vertices = elements;
143 for (std::size_t i=0; i<vertices.size(); ++i)
144 vertices[i]++;
145
146 insertVertices(factory, lowerLeft, upperRight, vertices);
147
148 // Compute the index offsets needed to move to the adjacent
149 // vertices in the different coordinate directions
150 std::array<unsigned int, dim> unitOffsets =
151 computeUnitOffsets(vertices);
152
153 // Compute an element template (the cube at (0,...,0). All
154 // other cubes are constructed by moving this template around
155 unsigned int nCorners = 1<<dim;
156
157 std::vector<unsigned int> cornersTemplate(nCorners,0);
158 for (std::size_t i=0; i<nCorners; ++i)
159 for (int j=0; j<dim; ++j)
160 if ( i & (1<<j) )
161 cornersTemplate[i] += unitOffsets[j];
162
163 // Insert elements
164 FactoryUtilities::MultiIndex<dim> index(elements);
165
166 // Compute the total number of elements to be created
167 int numElements = index.cycle();
168
169 for (int i=0; i<numElements; ++i, ++index) {
170
171 // 'base' is the index of the lower left element corner
172 unsigned int base = 0;
173 for (int j=0; j<dim; j++)
174 base += index[j] * unitOffsets[j];
175
176 // insert new element
177 std::vector<unsigned int> corners = cornersTemplate;
178 for (std::size_t j=0; j<corners.size(); ++j)
179 corners[j] += base;
180
181 insertElement(factory, GeometryTypes::simplex(dim), corners);
182 }
183 }
184 }
185
195 static std::unique_ptr<GridType> createSimplexGrid (
196 const FieldVector<ctype,dimworld>& lowerLeft,
197 const FieldVector<ctype,dimworld>& upperRight,
198 const std::array<unsigned int,dim>& elements)
199 {
200 GridFactory<GridType> factory;
201 createSimplexGrid(factory, lowerLeft, upperRight, elements);
202 return std::unique_ptr<GridType>(factory.createGrid());
203 }
204
205
207 const FieldVector<ctype,dimworld>& lowerLeft,
208 const FieldVector<ctype,dimworld>& upperRight,
209 const std::array<unsigned int,dim>& elements)
210 {
211 DUNE_THROW(Dune::NotImplemented,
212 "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
213 }
214
215 static std::unique_ptr<GridType> createCubeGrid (
216 const FieldVector<ctype,dimworld>& lowerLeft,
217 const FieldVector<ctype,dimworld>& upperRight,
218 const std::array<unsigned int,dim>& elements)
219 {
220 DUNE_THROW(Dune::NotImplemented,
221 "Cube grids are not supported by AlbertaGrid. Use createSimplexGrid instead.");
222 return nullptr;
223 }
224 };
225
226} // end namespace Dune
227
228#endif // HAVE_ALBERTA
229
230#endif // DUNE_ALBERTA_STRUCTUREDGRIDFACTORY_HH
Implements a multiindex with arbitrary dimension and fixed index ranges This is used by various facto...
Include standard header files.
Definition: agrid.hh:60
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
[ provides Dune::Grid ]
Definition: agrid.hh:109
GridFamily::ctype ctype
Definition: agrid.hh:143
Construct structured cube and simplex grids in unstructured grid managers.
Definition: utility/structuredgridfactory.hh:31
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::array< unsigned int, dim > computeUnitOffsets(const std::array< unsigned int, dim > &vertices)
Definition: albertagrid/structuredgridfactory.hh:110
static void createCubeGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Definition: albertagrid/structuredgridfactory.hh:206
typename GridType::ctype ctype
Definition: albertagrid/structuredgridfactory.hh:55
static void insertVertices(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &vertices)
Definition: albertagrid/structuredgridfactory.hh:82
static std::unique_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Definition: albertagrid/structuredgridfactory.hh:215
static void insertElement(GridFactory< GridType > &factory, const GeometryType &type, const std::vector< unsigned int > &vertices)
Definition: albertagrid/structuredgridfactory.hh:59
static void createSimplexGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
Create a structured simplex grid for AlbertaGrid.
Definition: albertagrid/structuredgridfactory.hh:134
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 for AlbertaGrid.
Definition: albertagrid/structuredgridfactory.hh:195
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.
A class to construct structured cube and simplex grids using the grid factory.