Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
makesphere.hh
Go to the documentation of this file.
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set ts=8 sw=4 et sts=4:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_MAKE_SPHERE_HH
8#define DUNE_FUFEM_MAKE_SPHERE_HH
9
10#include <cmath>
11#include <memory>
12#include <type_traits>
13
15
16#include <dune/grid/common/gridfactory.hh>
18
21{
22public:
27 const Dune::FieldVector<double,3>& center,
28 double radius)
29 : a_(a), b_(b), c_(c), d_(d), center_(center), radius_(radius)
30 {
31 assert( std::abs((a_ - center_).two_norm() - radius) < 1e-6 );
32 assert( std::abs((b_ - center_).two_norm() - radius) < 1e-6 );
33 assert( std::abs((c_ - center_).two_norm() - radius) < 1e-6 );
34 assert( std::abs((d_ - center_).two_norm() - radius) < 1e-6 );
35 }
36
38
40 result.axpy(local[0], b_-a_);
41 result.axpy(local[1], d_-a_);
42 result.axpy(local[0]*local[1], a_ + c_ -b_ -d_);
43
44 result *= radius_ / result.two_norm();
45 result += center_;
46
47 return result;
48 }
49
51
53
54 double radius_;
55};
56
59 : public Dune::BoundarySegment<3>
60{
61public:
65 const Dune::FieldVector<double,3>& center,
66 double radius)
67 : a_(a), b_(b), c_(c), center_(center), radius_(radius)
68 {
69 assert( std::abs((a_ - center_).two_norm() - radius) < 1e-6 );
70 assert( std::abs((b_ - center_).two_norm() - radius) < 1e-6 );
71 assert( std::abs((c_ - center_).two_norm() - radius) < 1e-6 );
72 }
73
75
77 result.axpy(local[0],b_-a_);
78 result.axpy(local[1],c_-a_);
79
80 result *= radius_ / result.two_norm();
81 result += center_;
82
83 return result;
84 }
85
87
89
90 double radius_;
91};
92
94template <class GridType, class field_type = double>
97 field_type radius)
98{
99 using namespace Dune;
100
102
103 // ////////////////////////
104 // Insert vertices
105 // ////////////////////////
107
108 double root = radius / std::sqrt(3);
109
110 for (int i=0; i<8; i++) {
111 pos[i] = center;
112 pos[i][0] += (i&1) ? root : -root;
113 pos[i][1] += (i&2) ? root : -root;
114 pos[i][2] += (i&4) ? root : -root;
115 factory.insertVertex(pos[i]);
116 }
117
118 factory.insertVertex(center);
119
120 unsigned int segments[12][3] = {{2, 0, 6}, {6, 0, 4},
121 {1, 3, 5}, {5, 3, 7},
122 {0, 1, 4}, {4, 1, 5},
123 {3, 2, 7}, {7, 2, 6},
124 {1, 0, 3}, {3, 0, 2},
125 {4, 5, 6}, {6, 5, 7}};
126
128 std::vector<unsigned int> cornerIDs(4);
129
130 for (int i=0; i<12; i++) {
131 for (int j=0; j<3; j++)
132 v[j] = segments[i][j];
133
134 auto boundarySegment = std::make_shared<SphereTriSegment>(pos[v[0]], pos[v[1]], pos[v[2]], center, radius);
135 factory.insertBoundarySegment(v,boundarySegment);
136
137 // /////////////////
138 // Insert elements
139 // /////////////////
140
141 cornerIDs = {segments[i][0], segments[i][1], segments[i][2], 8};
142 factory.insertElement(Dune::GeometryTypes::simplex(3), cornerIDs);
143 }
144
145 return std::unique_ptr<GridType>(factory.createGrid());
146}
147
149template <class GridType, class field_type = double>
151 field_type radius) {
152
153 static_assert(GridType::dimensionworld==3, "Only spheres in R^3 can be created!");
154
156
158 // Insert vertices
160
161 std::vector<Dune::FieldVector<double, 3> > pos = {{{1, 0, 0}}, {{0, 1, 0}}, {{-1, 0, 0}},
162 {{0, -1, 0}}, {{0, 0, 1}}, {{0, 0, -1}}};
163
164 for (int i=0; i<6; i++)
165 {
166 pos[i] *= radius;
167 pos[i] += center;
168 factory.insertVertex(pos[i]);
169 }
170
171 // 3d grids get a vertex at the sphere center
172 if (GridType::dimension==3)
173 factory.insertVertex(center);
174
175 // Insert elements
176 std::vector<std::vector<unsigned int> > segments = {{0, 1, 4}, {1, 2, 4},
177 {2, 3, 4}, {3, 0, 4},
178 {1, 0, 5}, {2, 1, 5},
179 {3, 2, 5}, {0, 3, 5}};
180
182
183 for (int i=0; i<8; i++)
184 {
185 // If the grid is sd the element boundaries carry a parametrization
187 [&](auto id)
188 {
189 auto boundarySegment = std::make_shared<SphereTriSegment>(pos[segments[i][0]],
190 pos[segments[i][1]],
191 pos[segments[i][2]], center, radius);
192 id(factory).insertBoundarySegment(segments[i], id(boundarySegment));
193
194 });
195
197 // Insert elements
199 if (GridType::dimension==2)
200 cornerIDs = {segments[i][0], segments[i][1], segments[i][2]};
201 else
202 cornerIDs = {segments[i][0], segments[i][1], segments[i][2], 6};
203
205 [&](auto id)
206 {
207 // Insert parametrized element
208 auto elementParametrization = std::make_shared<SphereTriSegment>(pos[segments[i][0]],
209 pos[segments[i][1]],
210 pos[segments[i][2]],
211 center,
212 radius);
213 id(factory).insertElement(Dune::GeometryTypes::simplex(GridType::dimension), cornerIDs, elementParametrization);
214 },
215 [&](auto id)
216 {
217 id(factory).insertElement(Dune::GeometryTypes::simplex(GridType::dimension), cornerIDs);
218 });
219 }
220 return std::unique_ptr<GridType>(factory.createGrid());
221}
222
223#endif
real_type two_norm() const
int id()
std::unique_ptr< GridType > makeSphere(const Dune::FieldVector< field_type, 3 > &center, field_type radius)
Create sphere grid from a cube and parameterised boundaries.
Definition makesphere.hh:95
std::unique_ptr< GridType > makeSphereOnOctahedron(const Dune::FieldVector< field_type, 3 > &center, field_type radius)
Create sphere grid from an octahedron and parameterised boundaries.
Definition makesphere.hh:150
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
LocalIndex & local()
constexpr FieldTraits< value_type >::real_type two_norm() const
constexpr derived_type & axpy(const field_type &a, const DenseVector< Other > &x)
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
virtual void insertVertex(const FieldVector< ctype, dimworld > &pos)
virtual void insertBoundarySegment(const std::vector< unsigned int > &vertices)
virtual std::unique_ptr< GridType > createGrid()
Class implementing a linear quadrilateral boundary segment.
Definition makesphere.hh:21
Dune::FieldVector< double, 3 > c_
Definition makesphere.hh:50
Dune::FieldVector< double, 3 > b_
Definition makesphere.hh:50
virtual Dune::FieldVector< double, 3 > operator()(const Dune::FieldVector< double, 2 > &local) const
Definition makesphere.hh:37
SphereQuadSegment(const Dune::FieldVector< double, 3 > &a, const Dune::FieldVector< double, 3 > &b, const Dune::FieldVector< double, 3 > &c, const Dune::FieldVector< double, 3 > &d, const Dune::FieldVector< double, 3 > &center, double radius)
Definition makesphere.hh:23
double radius_
Definition makesphere.hh:54
Dune::FieldVector< double, 3 > a_
Definition makesphere.hh:50
Dune::FieldVector< double, 3 > center_
Definition makesphere.hh:52
Dune::FieldVector< double, 3 > d_
Definition makesphere.hh:50
Class implementing a spherical triangular segment.
Definition makesphere.hh:60
virtual Dune::FieldVector< double, 3 > operator()(const Dune::FieldVector< double, 2 > &local) const
Definition makesphere.hh:74
Dune::FieldVector< double, 3 > b_
Definition makesphere.hh:86
Dune::FieldVector< double, 3 > center_
Definition makesphere.hh:88
SphereTriSegment(const Dune::FieldVector< double, 3 > &a, const Dune::FieldVector< double, 3 > &b, const Dune::FieldVector< double, 3 > &c, const Dune::FieldVector< double, 3 > &center, double radius)
Definition makesphere.hh:62
Dune::FieldVector< double, 3 > c_
Definition makesphere.hh:86
Dune::FieldVector< double, 3 > a_
Definition makesphere.hh:86
double radius_
Definition makesphere.hh:90
T forward(T... args)
T sqrt(T... args)