17#ifndef KASKADE_GRID_GENERATION_HH_
18#define KASKADE_GRID_GENERATION_HH_
20#include <boost/math/constants/constants.hpp>
29#include <dune/common/fvector.hh>
42 namespace GridGeneration_Detail
56 int dim = std::is_same_v<Type,Cube<typename Type::Real>>? 3: 2>
57 std::pair<std::vector<Dune::FieldVector<typename Type::Real,dim>>, std::vector<std::vector<unsigned int>>> extractSimplices(std::vector<Type>
const& cubes)
62 typename Type::Real tol = 1e-6;
63 auto vLess = [&](Vec
const& x, Vec
const& y)
65 for (
int i=0; i<dim; ++i)
68 else if (x[i] > y[i]+tol)
74 auto vEq = [&](Vec
const& x, Vec
const& y)
76 return !(vLess(x,y) || vLess(y,x));
81 std::vector<Vec> vertices;
82 for (
auto const& cube: cubes)
84 auto const& localVertices = cube.getVertices();
85 vertices.insert(vertices.end(),localVertices.begin(),localVertices.end());
87 std::sort(vertices.begin(),vertices.end(),vLess);
88 vertices.erase(std::unique(vertices.begin(),vertices.end(),vEq),vertices.end());
92 std::vector<std::vector<unsigned int>> tetrahedra;
94 for (Type
const& cube: cubes)
96 auto const& localVertices = cube.getVertices();
97 auto const& localTetrahedra = cube.getSimplices();
98 size_t const nVertices = localVertices.size();
101 std::vector<size_t> vertexIdMap(nVertices);
102 for(
size_t i=0; i<nVertices; ++i)
104 auto it = std::lower_bound(vertices.begin(),vertices.end(),localVertices[i],vLess);
105 assert(it != vertices.end());
106 vertexIdMap[i] = it - vertices.begin();
110 std::vector<unsigned int> newTet;
111 for(std::vector<unsigned int>
const& tet: localTetrahedra)
113 newTet.resize(tet.size());
114 for(
size_t i=0; i<newTet.size(); ++i)
115 newTet[i] = vertexIdMap[tet[i]];
116 tetrahedra.push_back(newTet);
120 return std::make_pair(vertices,tetrahedra);
132 template <
class Scalar>
135 std::vector<Square<Scalar> > squares;
137 for(
int i=0; i<2; ++i)
142 size_t xi_end = (size_t)round(fabs(dx[0]/dh2[0])),
143 yi_end = (
size_t)round(fabs(dx[1]/dh2[1]));
146 for(
size_t xi=0; xi<xi_end; ++xi)
148 x[0] = x0[0] + xi*dh2[0];
149 for(
size_t yi=0; yi<yi_end; ++yi)
151 x[1] = x0[1] + yi*dh2[1];
152 squares.push_back(Square<Scalar>(x,dsquare,symmetric));
167 template <
class Scalar>
181 template <
class Scalar>
185 std::vector<Cube<Scalar>> cubes;
188 for(
int i=0; i<3; ++i)
192 size_t xi_end = (size_t)round(fabs(dx[0]/dh2[0])),
193 yi_end = (
size_t)round(fabs(dx[1]/dh2[1])),
194 zi_end = (size_t)round(fabs(dx[2]/dh2[2]));
196 if (xi_end==0 || yi_end==0 || zi_end==0)
197 throw GridException(
"empty cubes list",__FILE__,__LINE__);
201 for(
size_t xi=0; xi<xi_end; ++xi)
203 x[0] = x0[0] + xi*dh2[0];
204 for(
size_t yi=0; yi<yi_end; ++yi)
206 x[1] = x0[1] + yi*dh2[1];
207 for(
size_t zi=0; zi<zi_end; ++zi)
209 x[2] = x0[2] + zi*dh2[2];
210 cubes.push_back(Cube<Scalar>(x,dh2,symmetric));
228 template <
class Scalar>
230 Scalar dh,
bool symmetric=
true)
237 template<
class Scalar,
int dim>
241 auto cubes = fillCuboid(x0,dx1,dh1,symmetric);
243 x0[dim-1] += dx1[dim-1];
244 auto cubes2 = fillCuboid(x0,dx2,dh2,symmetric);
245 for( Cube<Scalar>
const& cube : cubes2 ) cubes.push_back(cube);
250 template<
class Scalar,
int dim>
254 auto cubes = fillCuboid(x0,dx1,dh1,symmetric);
256 x0[dim-1] += dx1[dim-1];
257 auto cubes2 = fillCuboid(x0,dx2,dh2,symmetric);
258 for( Cube<Scalar>
const& cube : cubes2 ) cubes.push_back(cube);
269 template <
class Scalar,
class EdgeLength>
271 EdgeLength
const& dh,
bool symmetric=
true)
273 return fillCuboid(x0, dx, dh, symmetric);
280 template <
class Scalar,
class EdgeLength>
283 return fillRectangle(x0, dx, dh, symmetric);
298 template <
class Scalar,
int dim>
299 std::vector< typename std::conditional<dim==3,Cube<Scalar>,Square<Scalar> >::type >
304 auto cubes = FillCuboid<dim>::apply(x0,d0,dh,symmetric);
307 d0 = thickness; d0[1] = dy;
308 x0[1] += thickness[1];
309 auto cubes2 = FillCuboid<dim>::apply(x0,d0,dh,symmetric);
312 for(
auto const& cube : cubes2)
313 cubes.push_back(cube);
328 template <
class Scalar,
int dim>
329 std::vector< typename std::conditional<dim==3,Cube<Scalar>,Square<Scalar>>::type>
333 x0[0] -= 0.5*thickness[0];
335 auto cubes = FillCuboid<dim>::apply(x0,d0,dh,symmetric);
338 x0[0] += 0.5*thickness[0] - 0.5*dx;
340 d0[1] = thickness[1]; d0[0] = dx;
341 auto cubes2 = FillCuboid<dim>::apply(x0,d0,dh,symmetric);
344 for(
auto const& cube : cubes2) cubes.push_back(cube);
370 template <
class Gr
id,
class Type>
371 std::unique_ptr<Grid>
createGrid(std::vector<Type>
const& cubes)
374 timer.
start(
"extract simplices");
375 auto simplices = GridGeneration_Detail::extractSimplices(cubes);
376 timer.
stop(
"extract simplices");
377 Dune::GridFactory<Grid> factory;
378 Dune::GeometryType gt(Dune::GeometryType::simplex,Type::dim);
380 timer.
start(
"insert vertex");
382 factory.insertVertex(vertex);
383 timer.
stop(
"insert vertex");
384 timer.
start(
"insert element");
385 for (std::vector<unsigned int>
const& elem: simplices.second)
386 factory.insertElement(gt,elem);
387 timer.
stop(
"insert element");
389 return std::unique_ptr<Grid>(factory.createGrid());
413 template <
class Gr
id,
class Scalar,
int dim,
class EdgeLength>
415 EdgeLength
const& dh,
bool symmetric=
true)
418 timer.
start(
"create cubes");
419 auto const& cubes = GridGeneration_Detail::FillCuboid<dim>::apply(x0,dx,dh,symmetric);
420 timer.
stop(
"create cubes");
421 return createGrid<Grid>(cubes);
430 template <
class Gr
id>
434 return createCuboid<Grid>(Vec(0.), Vec(1.), dh, symmetric);
442 template <
class Gr
id>
446 return createCuboid<Grid>(Vec(0.), Vec(1.), dh, symmetric);
459 template <
class Gr
id,
class Scalar>
462 return createGrid<Grid>(GridGeneration_Detail::fillRectangle(x0,dx,dh,symmetric));
476 template <
class Gr
id,
class Scalar,
int dim>
481 return createGrid<Grid>(GridGeneration_Detail::fillLShape(x0,dx,dy,thickness,dh,symmetric));
495 template <
class Gr
id,
class Scalar,
int dim>
498 return createGrid<Grid>(GridGeneration_Detail::fillTShape(x0,dx,dy,thickness,dh,symmetric));
504 template <
class Gr
id,
class Scalar,
int dim>
508 return createGrid<Grid>(GridGeneration_Detail::fillTwoLayerCuboid(x0,dx1,dx2,dh1,dh2,symmetric));
514 template <
class Gr
id,
class Scalar,
int dim>
518 return createGrid<Grid>(GridGeneration_Detail::fillTwoLayerCuboid(x0,dx1,dx2,dh1,dh2,symmetric));
538 template <
class Gr
id>
541 Dune::GridFactory<Grid> factory;
542 Dune::GeometryType gt(Dune::GeometryType::simplex,3);
544 for (
int i=0; i<2; ++i)
545 for (
int j=0; j<2; ++j)
546 for (
int k=0; k<2; ++k)
552 factory.insertVertex(x);
555 factory.insertElement(gt,std::vector<unsigned int>{7,1,4,2});
556 factory.insertElement(gt,std::vector<unsigned int>{0,4,1,2});
557 factory.insertElement(gt,std::vector<unsigned int>{5,1,4,7});
558 factory.insertElement(gt,std::vector<unsigned int>{6,2,4,7});
559 factory.insertElement(gt,std::vector<unsigned int>{3,1,7,2});
561 return std::unique_ptr<Grid>(factory.createGrid());
573 template <
class Gr
id>
576 Dune::GridFactory<Grid> factory;
577 Dune::GeometryType gt(Dune::GeometryType::simplex,3);
579 for (
int i=0; i<3; ++i)
583 factory.insertVertex(x);
584 factory.insertVertex(-x);
588 factory.insertElement(gt,std::vector<unsigned int>{0,2,4,6});
589 factory.insertElement(gt,std::vector<unsigned int>{0,3,4,6});
590 factory.insertElement(gt,std::vector<unsigned int>{0,2,5,6});
591 factory.insertElement(gt,std::vector<unsigned int>{0,3,5,6});
592 factory.insertElement(gt,std::vector<unsigned int>{1,2,4,6});
593 factory.insertElement(gt,std::vector<unsigned int>{1,3,4,6});
594 factory.insertElement(gt,std::vector<unsigned int>{1,2,5,6});
595 factory.insertElement(gt,std::vector<unsigned int>{1,3,5,6});
597 return std::unique_ptr<Grid>(factory.createGrid());
608 template <
class Gr
id>
611 Dune::GridFactory<Grid> factory;
612 Dune::GeometryType gt(Dune::GeometryType::simplex,3);
614 auto vector = [=](
double x,
double y,
double z)
617 p[0] = x; p[1] = y; p[2] = z;
621 double s = (1+std::sqrt(5))/2;
623 factory.insertVertex(vector( 0, 1, s));
624 factory.insertVertex(vector( 0, 1,-s));
625 factory.insertVertex(vector( 0,-1, s));
626 factory.insertVertex(vector( 0,-1,-s));
627 factory.insertVertex(vector( 1, s, 0));
628 factory.insertVertex(vector( 1,-s, 0));
629 factory.insertVertex(vector(-1, s, 0));
630 factory.insertVertex(vector(-1,-s, 0));
631 factory.insertVertex(vector( s, 0, 1));
632 factory.insertVertex(vector( s, 0,-1));
633 factory.insertVertex(vector(-s, 0, 1));
634 factory.insertVertex(vector(-s, 0,-1));
635 factory.insertVertex(vector( 0, 0, 0));
637 factory.insertElement(gt,std::vector<unsigned int>{0,2, 8,12});
638 factory.insertElement(gt,std::vector<unsigned int>{0,2,10,12});
639 factory.insertElement(gt,std::vector<unsigned int>{1,3, 9,12});
640 factory.insertElement(gt,std::vector<unsigned int>{1,3,11,12});
642 factory.insertElement(gt,std::vector<unsigned int>{4,6, 0,12});
643 factory.insertElement(gt,std::vector<unsigned int>{4,6, 1,12});
644 factory.insertElement(gt,std::vector<unsigned int>{5,7, 2,12});
645 factory.insertElement(gt,std::vector<unsigned int>{5,7, 3,12});
647 factory.insertElement(gt,std::vector<unsigned int>{8,9, 4,12});
648 factory.insertElement(gt,std::vector<unsigned int>{8,9, 5,12});
649 factory.insertElement(gt,std::vector<unsigned int>{10,11,6,12});
650 factory.insertElement(gt,std::vector<unsigned int>{10,11,7,12});
652 factory.insertElement(gt,std::vector<unsigned int>{0,4, 8,12});
653 factory.insertElement(gt,std::vector<unsigned int>{0,6,10,12});
654 factory.insertElement(gt,std::vector<unsigned int>{3,7,11,12});
655 factory.insertElement(gt,std::vector<unsigned int>{3,5,9,12});
656 factory.insertElement(gt,std::vector<unsigned int>{1,4,9,12});
657 factory.insertElement(gt,std::vector<unsigned int>{1,6,11,12});
658 factory.insertElement(gt,std::vector<unsigned int>{2,7,10,12});
659 factory.insertElement(gt,std::vector<unsigned int>{2,5,8,12});
661 return std::unique_ptr<Grid>(factory.createGrid());
682 template <
class Gr
id>
683 std::unique_ptr<Grid>
createCylinder(
double radius,
double height,
int layers,
int circumEdges=6)
685 return createCylinder<Grid>(radius,height,layers,circumEdges,[](
auto const& x) {
return x; });
704 template <
class Gr
id,
class Deformation>
705 std::unique_ptr<Grid>
createCylinder(
double radius,
double height,
int layers,
int circumEdges,
706 Deformation
const& deformation)
708 using boost::math::double_constants::pi;
710 Dune::GridFactory<Grid> factory;
711 Dune::GeometryType gt(Dune::GeometryType::simplex,3);
713 auto vector = [](
double x,
double y,
double z)
716 p[0] = x; p[1] = y; p[2] = z;
720 double h = height/layers;
722 for (
int i=0; i<=layers; ++i)
725 factory.insertVertex(deformation(vector(0,0,z)));
726 for (
int j=0; j<circumEdges; ++j)
729 double angle = 2*pi*j/circumEdges;
730 auto v = vector(radius*std::cos(angle),radius*std::sin(angle),z);
731 factory.insertVertex(deformation(v));
738 for (
int i=0; i<layers; ++i)
742 int n = circumEdges+1;
745 unsigned int c0 = idxOffset;
746 unsigned int c1 = idxOffset+n;
748 for (
int j=0; j<circumEdges; ++j)
750 unsigned int a0 = c0+1+j;
751 unsigned int b0 = c0+1+(j+1)%circumEdges;
752 unsigned int a1 = c1+1+j;
753 unsigned int b1 = c1+1+(j+1)%circumEdges;
754 factory.insertElement(gt,std::vector<unsigned int>{a0,b0,c0,c1});
755 factory.insertElement(gt,std::vector<unsigned int>{a0,b1,a1,c1});
756 factory.insertElement(gt,std::vector<unsigned int>{a0,b0,b1,c1});
760 return std::unique_ptr<Grid>(factory.createGrid());
774 template <
class Gr
id>
778 Dune::GridFactory<Grid> factory;
779 Dune::GeometryType gt(Dune::GeometryType::simplex,2);
781 auto vector = [=](
double x,
double y)
788 double c1, c2, s1, s2;
789 c1 = 0.25*(std::sqrt(5)-1);
790 c2 = 0.25*(std::sqrt(5)+1);
791 s1 = 0.25*(std::sqrt(10+2*std::sqrt(5)));
792 s2 = 0.25*(std::sqrt(10-2*std::sqrt(5)));
794 factory.insertVertex(radius*vector( 1., 0.));
795 factory.insertVertex(radius*vector( c1, s1));
796 factory.insertVertex(radius*vector(-1.*c2,s2));
797 factory.insertVertex(radius*vector(-1.*c2,-1.*s2));
798 factory.insertVertex(radius*vector( c1, -1.0*s1));
799 factory.insertVertex(radius*vector( 0., 0.));
802 factory.insertElement(gt,std::vector<unsigned int>{0,1,5});
803 factory.insertElement(gt,std::vector<unsigned int>{1,2,5});
804 factory.insertElement(gt,std::vector<unsigned int>{2,3,5});
805 factory.insertElement(gt,std::vector<unsigned int>{3,4,5});
806 factory.insertElement(gt,std::vector<unsigned int>{4,0,5});
808 return std::unique_ptr<Grid>(factory.createGrid());
829 template <
class Gr
id>
836 Dune::GridFactory<Grid> factory;
837 Dune::GeometryType gt(Dune::GeometryType::simplex,2);
839 auto vector = [=](
double x,
double y)
846 factory.insertVertex(vector( 0, 0));
847 factory.insertVertex(vector( (l+d)/2, 0));
848 factory.insertVertex(vector( l, 0));
849 factory.insertVertex(vector( l, d));
850 factory.insertVertex(vector( (l+d)/2, d));
851 factory.insertVertex(vector( d, d));
852 factory.insertVertex(vector( d, d+eps));
853 factory.insertVertex(vector( (l+d)/2, d+eps));
854 factory.insertVertex(vector( l, d+eps));
855 factory.insertVertex(vector( l, 2*d+eps));
856 factory.insertVertex(vector( (l+d)/2, 2*d+eps));
857 factory.insertVertex(vector( 0, 2*d+eps));
858 factory.insertVertex(vector( 0, d+eps/2));
860 factory.insertElement(gt,std::vector<unsigned int>{0,1,5});
861 factory.insertElement(gt,std::vector<unsigned int>{1,4,5});
862 factory.insertElement(gt,std::vector<unsigned int>{1,2,4});
863 factory.insertElement(gt,std::vector<unsigned int>{2,3,4});
864 factory.insertElement(gt,std::vector<unsigned int>{5,6,12});
865 factory.insertElement(gt,std::vector<unsigned int>{6,7,10});
866 factory.insertElement(gt,std::vector<unsigned int>{7,8,9});
867 factory.insertElement(gt,std::vector<unsigned int>{7,9,10});
868 factory.insertElement(gt,std::vector<unsigned int>{6,10,11});
869 factory.insertElement(gt,std::vector<unsigned int>{6,11,12});
870 factory.insertElement(gt,std::vector<unsigned int>{0,5,12});
872 return std::unique_ptr<Grid>(factory.createGrid());
Supports gathering and reporting execution times information for nested program parts.
static Timings & instance()
Returns a reference to a single default instance.
void stop(std::string const &name)
Stops the timing of given section.
struct Times const * start(std::string const &name)
Starts or continues the timing of given section.
This file contains various utility functions that augment the basic functionality of Dune.
std::unique_ptr< Grid > createIcosahedron()
Creates an icosahedron consisting of 20 tetrahedra.
std::unique_ptr< Grid > createOctahedron(Dune::FieldVector< typename Grid::ctype, 3 > extent=Dune::FieldVector< typename Grid::ctype, 3 >(1.0))
Creates an octahedron consisting of eight tetrahedra.
std::unique_ptr< Grid > createHexahedron()
Creates a hexahedron consisting of five tetrahedra.