21 #ifndef bempp_structured_grid_factory_hpp
22 #define bempp_structured_grid_factory_hpp
24 #include "../common/common.hpp"
35 #include <dune/common/array.hh>
36 #include <dune/common/classname.hh>
37 #include <dune/common/exceptions.hh>
38 #include <dune/common/fvector.hh>
39 #include <dune/common/mpihelper.hh>
41 #include <dune/grid/common/gridfactory.hh>
42 #include <dune/grid/yaspgrid.hh>
55 template <
class Gr
idType>
58 typedef typename GridType::ctype ctype;
60 static const int dim = GridType::dimension;
62 static const int dimworld = GridType::dimensionworld;
67 :
public array<int,dim>
71 array<int,dim> limits_;
77 std::fill(this->begin(), this->end(), 0);
83 for (
int i=0; i<dim; i++) {
89 if ((*
this)[i]<limits_[i])
101 for (
int i=0; i<dim; i++)
102 result *= limits_[i];
110 const FieldVector<ctype,dim>& lowerLeft,
111 const FieldVector<ctype,dim>& upperRight,
112 const array<int,dim>& vertices) {
115 FieldVector<ctype,dimworld> fullLowerLeft(0.);
116 for (
int i = 0; i < dim; ++i)
117 fullLowerLeft[i] = lowerLeft[i];
118 FieldVector<ctype,dimworld> fullUpperRight(0.);
119 for (
int i = 0; i < dim; ++i)
120 fullUpperRight[i] = upperRight[i];
125 int numVertices = index.
cycle();
128 for (
int i=0; i<numVertices; i++, ++index) {
131 FieldVector<double,dimworld> pos(0);
132 for (
int j=0; j<dim; j++)
133 pos[j] = fullLowerLeft[j] + index[j] * (fullUpperRight[j]-fullLowerLeft[j])/(vertices[j]-1);
135 factory.insertVertex(pos);
143 static array<int, dim> computeUnitOffsets(
const array<int,dim>& vertices) {
144 array<int, dim> unitOffsets;
148 for (
int i=1; i<dim; i++)
149 unitOffsets[i] = unitOffsets[i-1] * vertices[i-1];
161 static std::auto_ptr<GridType>
createCubeGrid(
const FieldVector<ctype,dim>& lowerLeft,
162 const FieldVector<ctype,dim>& upperRight,
163 const array<int,dim>& elements) {
165 GridFactory<GridType> factory;
167 if (MPIHelper::getCollectiveCommunication().rank() == 0) {
169 array<int,dim> vertices = elements;
170 for(
int i = 0; i < vertices.size(); ++i )
178 array<int, dim> unitOffsets =
179 computeUnitOffsets(vertices);
183 int nCorners = 1<<dim;
185 std::vector<int> cornersTemplate(nCorners,0);
187 for (
int i=0; i<nCorners; i++)
188 for (
int j=0; j<dim; j++)
190 cornersTemplate[i] += unitOffsets[j];
196 int numElements = index.
cycle();
198 for (
int i=0; i<numElements; i++, ++index) {
202 for (
int j=0; j<dim; j++)
203 base += index[j] * unitOffsets[j];
206 std::vector<int> corners = cornersTemplate;
207 for (
size_t j=0; j<corners.size(); j++)
210 factory.insertElement
218 return std::auto_ptr<GridType>(factory.createGrid());
229 const FieldVector<ctype,dim>& upperRight,
230 const array<int,dim>& elements) {
232 GridFactory<GridType> factory;
234 if(MPIHelper::getCollectiveCommunication().rank() == 0) {
236 array<int,dim> vertices = elements;
237 for (std::size_t i=0; i<vertices.size(); i++)
244 array<int, dim> unitOffsets =
245 computeUnitOffsets(vertices);
248 std::vector<int> corners(dim+1);
253 int cycle = elementsIndex.
cycle();
255 for (
int i=0; i<cycle; ++elementsIndex, i++) {
259 for (
int j=0; j<dim; j++)
260 base += elementsIndex[j] * unitOffsets[j];
263 std::vector<unsigned int> permutation(dim);
264 for (
int j=0; j<dim; j++)
274 std::vector<unsigned int> corners(dim+1);
277 for (
int j=0; j<dim; j++)
279 corners[j] + unitOffsets[permutation[j]];
280 if (dim == 2 && triangle == 1)
281 std::swap(corners[1], corners[2]);
284 factory.insertElement
288 }
while (std::next_permutation(permutation.begin(),
296 return std::auto_ptr<GridType>(factory.createGrid());
313 typedef YaspGrid<dim> GridType;
314 typedef typename GridType::ctype ctype;
315 static const int dimworld = GridType::dimensionworld;
327 static std::auto_ptr<GridType>
329 const FieldVector<ctype,dimworld>& upperRight,
330 const array<int,dim>& elements) {
331 for(
int d = 0; d < dimworld; ++d)
332 if(std::abs(lowerLeft[d]) > std::abs(upperRight[d])*1e-10)
333 DUNE_THROW(GridError, className<BemppStructuredGridFactory>()
334 <<
"::createCubeGrid(): The lower coordinates "
335 "must be at the origin for YaspGrid.");
337 FieldVector<int, dim> elements_;
338 std::copy(elements.begin(), elements.end(), elements_.begin());
340 return std::auto_ptr<GridType>
341 (
new GridType(upperRight, elements_,
342 FieldVector<bool,dim>(
false), 0));
350 static std::auto_ptr<GridType>
352 const FieldVector<ctype,dimworld>& upperRight,
353 const array<int,dim>& elements) {
354 DUNE_THROW(GridError, className<BemppStructuredGridFactory>()
355 <<
"::createSimplexGrid(): Simplices are not supported "
static std::auto_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< int, dim > &elements)
Create a structured simplex grid.
Definition: structured_grid_factory.hpp:351
static std::auto_ptr< GridType > createCubeGrid(const FieldVector< ctype, dim > &lowerLeft, const FieldVector< ctype, dim > &upperRight, const array< int, dim > &elements)
Create a structured cube grid.
Definition: structured_grid_factory.hpp:161
Dune::GeometryType GeometryType
Identifier of geometry type.
Definition: geometry_type.hpp:34
static std::auto_ptr< GridType > createSimplexGrid(const FieldVector< ctype, dim > &lowerLeft, const FieldVector< ctype, dim > &upperRight, const array< int, dim > &elements)
Create a structured simplex grid.
Definition: structured_grid_factory.hpp:228
static std::auto_ptr< GridType > createCubeGrid(const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const array< int, dim > &elements)
Create a structured cube grid.
Definition: structured_grid_factory.hpp:328
MultiIndex(const array< int, dim > &limits)
Constructor with a given range for each digit.
Definition: structured_grid_factory.hpp:75
static void insertVertices(GridFactory< GridType > &factory, const FieldVector< ctype, dim > &lowerLeft, const FieldVector< ctype, dim > &upperRight, const array< int, dim > &vertices)
Insert a structured set of vertices into the factory.
Definition: structured_grid_factory.hpp:109
MultiIndex & operator++()
Increment the MultiIndex.
Definition: structured_grid_factory.hpp:81
Construct structured cube and simplex grids in unstructured grid managers.
Definition: structured_grid_factory.hpp:56
dim-dimensional multi-index. The range for each component can be set individually ...
Definition: structured_grid_factory.hpp:66
int cycle() const
Compute how many times you can call operator++ before getting to (0,...,0) again. ...
Definition: structured_grid_factory.hpp:99