KASKADE 7 development version
cube.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2013-2022 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12#ifndef KASKADE_CUBE_HH
13#define KASKADE_CUBE_HH
14
15#include <algorithm>
16#include <cmath>
17#include <utility>
18#include <vector>
19
20#include <dune/common/fvector.hh>
21
22namespace Kaskade
23{
24 template <class Real, int dim_>
26 {
27 public:
28 static constexpr int dim = dim_;
29
30 BasicGridElement() : vertices(), simplices(), pi(3.141592653589793){}
31
32 BasicGridElement(BasicGridElement const& other) = default;
33
35 {
36 *this = std::move(other);
37 }
38
40
42 {
43 vertices = std::move(other.vertices);
44 simplices = std::move(other.simplices);
45 pi = other.pi;
46 return *this;
47 }
48
49 std::vector<Dune::FieldVector<Real,dim> > const& getVertices() const { return vertices; }
50 std::vector<std::vector<unsigned int> > const& getSimplices() const { return simplices; }
51
52 protected:
53 std::vector<Dune::FieldVector<Real,dim> > vertices;
54 std::vector<std::vector<unsigned int> > simplices;
55 Real pi;
56 };
57
58
59 template <class Real_=double>
60 class Square : public BasicGridElement<Real_,2>
61 {
62 public:
63 typedef Real_ Real;
64
65 explicit Square(bool symmetric=false) : Square(Dune::FieldVector<Real,2>(0.0), Dune::FieldVector<Real,2>(1.0),symmetric)
66 {}
67
68 Square(Dune::FieldVector<Real,2> const& x0, Dune::FieldVector<Real,2> const& dx, bool symmetric=false)
69 {
70 if(!symmetric)
71 {
72 initVertices(x0[0],x0[1],dx[0],dx[1]);
73 initTriangles();
74 }
75 else
76 {
77 initSymmetricVertices(x0[0],x0[1],dx[0],dx[1]);
78 initSymmetricTriangles();
79 }
80 }
81
82 private:
85
86 void initVertices(Real x, Real y, Real dx, Real dy)
87 {
89 v[0] = x; v[1] = y; vertices.push_back(v);
90 v[0] = x+dx; v[1] = y; vertices.push_back(v);
91 v[0] = x; v[1] = y+dy; vertices.push_back(v);
92 v[0] = x+dx; v[1] = y+dy; vertices.push_back(v);
93 }
94
95 void initSymmetricVertices(Real x, Real y, Real dx, Real dy)
96 {
98 v[0] = x; v[1] = y; vertices.push_back(v);
99 v[0] = x+dx; v[1] = y; vertices.push_back(v);
100 v[0] = x+dx; v[1] = y+dy; vertices.push_back(v);
101 v[0] = x; v[1] = y+dy; vertices.push_back(v);
102 v[0] = x+0.5*dx; v[1] = y+0.5*dx; vertices.push_back(v);
103 }
104
105 void initTriangles()
106 {
107 std::vector<unsigned int> p(3,0);
108
109 p[0] = 0; p[1] = 1; p[2] = 3; simplices.push_back(p);
110 p[0] = 0; p[1] = 3; p[2] = 2; simplices.push_back(p);
111 }
112
113 void initSymmetricTriangles()
114 {
115 std::vector<unsigned int> p(3,0);
116
117 p[0] = 0; p[1] = 1; p[2] = 4; simplices.push_back(p);
118 p[0] = 1; p[1] = 2; p[2] = 4; simplices.push_back(p);
119 p[0] = 2; p[1] = 3; p[2] = 4; simplices.push_back(p);
120 p[0] = 3; p[1] = 0; p[2] = 4; simplices.push_back(p);
121 }
122 };
123
124 template <class Real_=double>
125 class Cube : public BasicGridElement<Real_,3>
126 {
127 public:
128 typedef Real_ Real;
129
130 // creates a standard cube
131 explicit Cube(bool symmetric=false) : Cube(Dune::FieldVector<Real,3>(0.0), Dune::FieldVector<Real,3>(1.0), symmetric)
132 {}
133
134 // creates a standard cube with the left, down, front corner in the point(x,y,z)
135 Cube(Dune::FieldVector<Real,3> const& x0, Dune::FieldVector<Real,3> const& dx, bool symmetric)
136 {
137 if (!symmetric)
138 {
139 initVertices(x0[0],x0[1],x0[2],dx[0],dx[1],dx[2]);
140 initTetrahedra();
141 }
142 else
143 {
144 initSymmetricVertices(x0[0],x0[1],x0[2],dx[0],dx[1],dx[2]);
145 initSymmetricTetrahedra();
146 }
147 }
148
149 private:
152
153 void initVertices(Real x, Real y, Real z, Real dx, Real dy, Real dz)
154 {
156 //points in the frontside
157 v[0]=x; v[1]=y; v[2]=z; vertices.push_back(v);
158 v[0]=x+dx; v[1]=y; v[2]=z; vertices.push_back(v);
159 v[0]=x+dx; v[1]=y; v[2]=z+dz; vertices.push_back(v);
160 v[0]=x; v[1]=y; v[2]=z+dz; vertices.push_back(v);
161
162 //points in the backside
163 v[0]=x; v[1]=y+dy; v[2]=z; vertices.push_back(v);
164 v[0]=x+dx; v[1]=y+dy; v[2]=z; vertices.push_back(v);
165 v[0]=x+dx; v[1]=y+dy; v[2]=z+dz; vertices.push_back(v);
166 v[0]=x; v[1]=y+dy; v[2]=z+dz; vertices.push_back(v);
167
168 //point in the center
169 v[0]=x+0.5*dx; v[1]=y+0.5*dy ;v[2]=z+0.5*dz; vertices.push_back(v);
170 }
171
172 void initSymmetricVertices(Real x, Real y, Real z, Real dx, Real dy, Real dz)
173 {
175
176 // points on the frontside
177 v[0]=x; v[1]=y; v[2]=z; vertices.push_back(v); // 0
178 v[0]=x+dx; v[1]=y; v[2]=z; vertices.push_back(v); // 1
179 v[0]=x+dx; v[1]=y; v[2]=z+dz; vertices.push_back(v); // 2
180 v[0]=x; v[1]=y; v[2]=z+dz; vertices.push_back(v); // 3
181
182 // points on the backside
183 v[0]=x; v[1]=y+dy; v[2]=z; vertices.push_back(v); // 4
184 v[0]=x+dx; v[1]=y+dy; v[2]=z; vertices.push_back(v); // 5
185 v[0]=x+dx; v[1]=y+dy; v[2]=z+dz; vertices.push_back(v); // 6
186 v[0]=x; v[1]=y+dy; v[2]=z+dz; vertices.push_back(v); // 7
187
188 // point in the center
189 v[0]=x+0.5*dx; v[1]=y+0.5*dy; v[2]=z+0.5*dz; vertices.push_back(v); // 8
190
191 // points in the center of face
192 v[0]=x; v[1]=y+0.5*dy; v[2]=z+0.5*dz; vertices.push_back(v); // 9
193 v[0]=x+dx; v[1]=y+0.5*dy; v[2]=z+0.5*dz; vertices.push_back(v); // 10
194 v[0]=x+0.5*dx; v[1]=y; v[2]=z+0.5*dz; vertices.push_back(v); // 11
195 v[0]=x+0.5*dx; v[1]=y+dy; v[2]=z+0.5*dz; vertices.push_back(v); // 12
196 v[0]=x+0.5*dx; v[1]=y+0.5*dy; v[2]=z; vertices.push_back(v); // 13
197 v[0]=x+0.5*dx; v[1]=y+0.5*dy; v[2]=z+dz; vertices.push_back(v); // 14
198 }
199
200 void initSymmetricTetrahedra()
201 {
202 std::vector<unsigned int> p(4,0);
203
204 // bottom
205 p[0]=13; p[1]=1; p[2]=5; p[3]=8; simplices.push_back(p);
206 p[0]=13; p[1]=5; p[2]=4; p[3]=8; simplices.push_back(p);
207 p[0]=13; p[1]=4; p[2]=0; p[3]=8; simplices.push_back(p);
208 p[0]=13; p[1]=0; p[2]=1; p[3]=8; simplices.push_back(p);
209
210 // top
211 p[0]=14; p[1]=3; p[2]=2; p[3]=8; simplices.push_back(p);
212 p[0]=14; p[1]=2; p[2]=6; p[3]=8; simplices.push_back(p);
213 p[0]=14; p[1]=6; p[2]=7; p[3]=8; simplices.push_back(p);
214 p[0]=14; p[1]=7; p[2]=3; p[3]=8; simplices.push_back(p);
215
216 // right
217 p[0]=10; p[1]=6; p[2]=5; p[3]=8; simplices.push_back(p);
218 p[0]=10; p[1]=5; p[2]=1; p[3]=8; simplices.push_back(p);
219 p[0]=10; p[1]=1; p[2]=2; p[3]=8; simplices.push_back(p);
220 p[0]=10; p[1]=2; p[2]=6; p[3]=8; simplices.push_back(p);
221
222 // left
223 p[0]=9; p[1]=3; p[2]=0; p[3]=8; simplices.push_back(p);
224 p[0]=9; p[1]=0; p[2]=4; p[3]=8; simplices.push_back(p);
225 p[0]=9; p[1]=4; p[2]=7; p[3]=8; simplices.push_back(p);
226 p[0]=9; p[1]=7; p[2]=3; p[3]=8; simplices.push_back(p);
227
228 // front
229 p[0]=11; p[1]=1; p[2]=0; p[3]=8; simplices.push_back(p);
230 p[0]=11; p[1]=0; p[2]=3; p[3]=8; simplices.push_back(p);
231 p[0]=11; p[1]=3; p[2]=2; p[3]=8; simplices.push_back(p);
232 p[0]=11; p[1]=2; p[2]=1; p[3]=8; simplices.push_back(p);
233
234 // back
235 p[0]=12; p[1]=4; p[2]=5; p[3]=8; simplices.push_back(p);
236 p[0]=12; p[1]=5; p[2]=6; p[3]=8; simplices.push_back(p);
237 p[0]=12; p[1]=6; p[2]=7; p[3]=8; simplices.push_back(p);
238 p[0]=12; p[1]=7; p[2]=4; p[3]=8; simplices.push_back(p);
239 }
240
241 void initTetrahedra()
242 {
243 std::vector<unsigned int> p(4,0);
244
245 // front side
246 p[0]=0; p[1]=1; p[2]=2; p[3]=8; simplices.push_back(p);
247 p[0]=2; p[1]=3; p[2]=0; p[3]=8; simplices.push_back(p);
248
249 // back side
250 p[0]=6; p[1]=5; p[2]=4; p[3]=8; simplices.push_back(p);
251 p[0]=4; p[1]=6; p[2]=7; p[3]=8; simplices.push_back(p);
252
253 // right side
254 p[0]=6; p[1]=1; p[2]=5; p[3]=8; simplices.push_back(p);
255 p[0]=2; p[1]=1; p[2]=6; p[3]=8; simplices.push_back(p);
256
257 // left side
258 p[0]=0; p[1]=4; p[2]=7; p[3]=8; simplices.push_back(p);
259 p[0]=0; p[1]=7; p[2]=3; p[3]=8; simplices.push_back(p);
260
261 // bottom
262 p[0]=0; p[1]=1; p[2]=5; p[3]=8; simplices.push_back(p);
263 p[0]=0; p[1]=5; p[2]=4; p[3]=8; simplices.push_back(p);
264
265 // top
266 p[0]=3; p[1]=2; p[2]=6; p[3]=8; simplices.push_back(p);
267 p[0]=3; p[1]=6; p[2]=7; p[3]=8; simplices.push_back(p);
268 }
269 };
270
271 template <class Real_=double>
272 class Circle : public BasicGridElement<Real_,2>
273 {
274 public:
275 typedef Real_ Real;
276
277 // creates a circle
278 explicit Circle(bool symmetric=false) : Circle(Dune::FieldVector<Real,2>(0.0), 1., 8, symmetric)
279 {}
280
281 // creates a standard cube with the left, down, front corner in the point(x,y,z)
282 Circle(Dune::FieldVector<Real,2> const& center, Real radius, size_t nCorners, bool symmetric)
283 {
284 assert(nCorners>0);
285 Real localAngle = (2*pi)/nCorners;
286 Real ratio = 1./localAngle;
287
288 if(!symmetric)
289 {
290 initVertices(center, radius, localAngle, nCorners, symmetric);
291 initSimplices(nCorners, localAngle);
292 }
293 else
294 {
295 initSymmetricVertices(center, radius, localAngle, nCorners, symmetric);
296 initSymmetricTetrahedra();
297 }
298 }
299
300 private:
303 using BasicGridElement<Real,2>::pi;
304
305 Real log2(Real val)
306 {
307 return std::log(val)/std::log(2);
308 }
309
310 void initVertices(Dune::FieldVector<Real,2> const& center, Real radius, Real localAngle, size_t nCorners, bool symmetric)
311 {
312 size_t regFactor = (nCorners > 8) ? (size_t)round(log2(1/localAngle)) : 1;
313 Real div = 1./regFactor;
314 if(div < 1 ) div=0.5;
315
316 vertices.push_back(center);
317
319 size_t innerCorners = 8;
320 Real angle = pi*0.25;
321 for(size_t i=0; i<innerCorners; ++i)
322 {
323 v[0] = div * radius * sin(i*angle);
324 v[0] = div * radius * cos(i*angle);
325 vertices.push_back(v);
326 }
327
328// if(nCorners <= innerCorners) return;
329//
330// innerCorners *= 2;
331// angle *= 0.5;
332// div = 1;
333// for(size_t i=0; i<innerCorners; ++i)
334// {
335// v[0] = div * radius * sin(i*angle);
336// v[0] = div * radius * cos(i*angle);
337// vertices.push_back(v);
338// }
339
340// for(size_t i=0; i<regFactor; ++i)
341// {
342//
343// }
344//
345// if(regFactor > 1)
346// {
347// for(size_t i=0; i<nCorners; ++i)
348// {
349// v[0] = 0.5*radius * sin(i*localAngle);
350// v[1] = 0.5*radius * cos(i*localAngle);
351// vertices.push_back(v);
352// }
353// }
354//
355// for(size_t i=0; i<nCorners; ++i)
356// {
357// v[0] = radius * sin(i*localAngle);
358// v[1] = radius * cos(i*localAngle);
359// vertices.push_back(v);
360// }
361
362
363 }
364
365 void initSimplices(size_t nCorners, Real localAngle)
366 {
367 size_t regFactor = (nCorners > 8) ? (size_t)round(log2(1/localAngle)) : 1;
368 Real div = 1./regFactor;
369 if(div < 1 ) div=0.5;
370
371 // inner ring
372 std::vector<unsigned int> p(3,0);
373 for(size_t i=0; i<8; ++i)
374 {
375 p[1] = i+1;
376 if(i+2 > 8) p[2] = i+2-8;
377 else p[2] = i+2;
378 simplices.push_back(p);
379 }
380
381// // outer ring
382// size_t lastRingNoNodes = 8;
383// unsigned int a, b, c;
384// for(size_t i=1; i<=lastRingNoNodes; ++i)
385// {
386// a = lastRingNoNodes + 2*i - 1;
387// b = lastRingNoNodes + 2*i;
388// c = i;
389// addSimplex(a,b,c);
390//
391// a = i+1;
392// addSimplex(a,b,c);
393//
394// c = (b+1)==vertices.size() ? lastRingNoNodes+1 : b+1;
395// addSimplex(a,b,c);
396// }
397 }
398
399 void addSimplex(unsigned int a, unsigned int b, unsigned int c)
400 {
401 std::vector<unsigned int> p = { a, b, c };
402 simplices.push_back(p);
403 }
404
405 void initSymmetricVertices(Dune::FieldVector<Real,2> const& center, Real radius, Real localAngle, size_t nCorners, bool symmetric)
406 {
407 vertices.push_back(center);
408
410 for(size_t i=0; i<nCorners; ++i)
411 {
412 v[0] = radius * sin(i*localAngle);
413 v[1] = radius * cos(i*localAngle);
414 vertices.push_back(v);
415 }
416 }
417
418 void initSymmetricTetrahedra()
419 {
420
421 }
422 };
423
424} // end namespace Kaskade
425
426#endif
BasicGridElement(BasicGridElement &&other)
Definition: cube.hh:34
std::vector< std::vector< unsigned int > > const & getSimplices() const
Definition: cube.hh:50
BasicGridElement & operator=(BasicGridElement const &other)=default
BasicGridElement(BasicGridElement const &other)=default
std::vector< std::vector< unsigned int > > simplices
Definition: cube.hh:54
static constexpr int dim
Definition: cube.hh:28
std::vector< Dune::FieldVector< Real, dim > > const & getVertices() const
Definition: cube.hh:49
std::vector< Dune::FieldVector< Real, dim > > vertices
Definition: cube.hh:53
BasicGridElement & operator=(BasicGridElement &&other)
Definition: cube.hh:41
Real_ Real
Definition: cube.hh:275
Circle(bool symmetric=false)
Definition: cube.hh:278
Circle(Dune::FieldVector< Real, 2 > const &center, Real radius, size_t nCorners, bool symmetric)
Definition: cube.hh:282
Cube(bool symmetric=false)
Definition: cube.hh:131
Cube(Dune::FieldVector< Real, 3 > const &x0, Dune::FieldVector< Real, 3 > const &dx, bool symmetric)
Definition: cube.hh:135
Real_ Real
Definition: cube.hh:128
Square(Dune::FieldVector< Real, 2 > const &x0, Dune::FieldVector< Real, 2 > const &dx, bool symmetric=false)
Definition: cube.hh:68
Square(bool symmetric=false)
Definition: cube.hh:65
Real_ Real
Definition: cube.hh:63