3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
boxgeometryhelper.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_DISCRETIZATION_BOX_GEOMETRY_HELPER_HH
26#define DUMUX_DISCRETIZATION_BOX_GEOMETRY_HELPER_HH
27
28#include <array>
29#include <dune/geometry/referenceelements.hh>
30
31#include <dumux/common/math.hh>
32
33namespace Dumux {
34
36template<class GridView, int dim, class ScvType, class ScvfType>
38
40template <class GridView, class ScvType, class ScvfType>
41class BoxGeometryHelper<GridView, 1, ScvType, ScvfType>
42{
43private:
44 using Scalar = typename GridView::ctype;
45 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
46 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
47 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
48
49 using Element = typename GridView::template Codim<0>::Entity;
50 using Intersection = typename GridView::Intersection;
51
54 static constexpr int maxPoints = 3;
55
56public:
57
58 BoxGeometryHelper(const typename Element::Geometry& geometry)
59 : elementGeometry_(geometry), corners_(geometry.corners()),
60 p_({geometry.center(), geometry.corner(0), geometry.corner(1)}) {}
61
63 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
64 {
66 static const std::uint8_t map[2][2] =
67 {
68 {1, 0},
69 {2, 0}
70 };
71
72 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
73 p_[map[localScvIdx][1]]} };
74 }
75
77 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
78 {
79 return ScvfCornerStorage{{p_[0]}};
80 }
81
83 ScvfCornerStorage getBoundaryScvfCorners(const Intersection& is,
84 const typename Intersection::Geometry& geometry,
85 unsigned int indexInIntersection) const
86 {
87 return ScvfCornerStorage{{geometry.corner(0)}};
88 }
89
91 GlobalPosition normal(const ScvfCornerStorage& scvfCorners,
92 const std::vector<unsigned int>& scvIndices) const
93 {
94 auto normal = p_[2] - p_[1];
95 normal /= normal.two_norm();
96 return normal;
97 }
98
100 Scalar scvVolume(const ScvCornerStorage& scvCorners) const
101 {
102 return (scvCorners[1] - scvCorners[0]).two_norm();
103 }
104
106 Scalar scvfArea(const ScvfCornerStorage& scvfCorners) const
107 {
108 return 1.0;
109 }
110
111protected:
112 const typename Element::Geometry& elementGeometry_;
113 std::size_t corners_; // number of element corners
114 std::array<GlobalPosition, maxPoints> p_; // the points needed for construction of the geometries
115};
116
118template <class GridView, class ScvType, class ScvfType>
119class BoxGeometryHelper<GridView, 2, ScvType, ScvfType>
120{
121 using Scalar = typename GridView::ctype;
122 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
123 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
124 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
125
126 using Element = typename GridView::template Codim<0>::Entity;
127 using Intersection = typename GridView::Intersection;
128
129 static constexpr auto dim = GridView::dimension;
130 static constexpr auto dimWorld = GridView::dimensionworld;
131 using ReferenceElements = typename Dune::ReferenceElements<Scalar, dim>;
132
135 static constexpr int maxPoints = 9;
136
137public:
138
139 BoxGeometryHelper(const typename Element::Geometry& geometry)
140 : elementGeometry_(geometry)
141 , corners_(geometry.corners())
142 {
143 const auto referenceElement = ReferenceElements::general(geometry.type());
144
145 // the element center
146 p_[0] = geometry.center();
147
148 // vertices
149 for (int i = 0; i < corners_; ++i)
150 p_[i+1] = geometry.corner(i);
151
152 // face midpoints
153 for (int i = 0; i < referenceElement.size(1); ++i)
154 p_[i+corners_+1] = geometry.global(referenceElement.position(i, 1));
155 }
156
158 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
159 {
160 // proceed according to number of corners of the element
161 switch (corners_)
162 {
163 case 3: // triangle
164 {
166 static const std::uint8_t vo = 1;
167 static const std::uint8_t fo = 4;
168 static const std::uint8_t map[3][4] =
169 {
170 {vo+0, fo+0, fo+1, 0},
171 {vo+1, fo+2, fo+0, 0},
172 {vo+2, fo+1, fo+2, 0}
173 };
174
175 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
176 p_[map[localScvIdx][1]],
177 p_[map[localScvIdx][2]],
178 p_[map[localScvIdx][3]]} };
179 }
180 case 4: // quadrilateral
181 {
183 static const std::uint8_t vo = 1;
184 static const std::uint8_t fo = 5;
185 static const std::uint8_t map[4][4] =
186 {
187 {vo+0, fo+2, fo+0, 0},
188 {vo+1, fo+1, fo+2, 0},
189 {vo+2, fo+0, fo+3, 0},
190 {vo+3, fo+3, fo+1, 0}
191 };
192
193 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
194 p_[map[localScvIdx][1]],
195 p_[map[localScvIdx][2]],
196 p_[map[localScvIdx][3]]} };
197 }
198 default:
199 DUNE_THROW(Dune::NotImplemented, "Box scv geometries for dim=" << dim
200 << " dimWorld=" << dimWorld
201 << " corners=" << corners_);
202 }
203 }
204
205
207 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
208 {
209 // proceed according to number of corners
210 switch (corners_)
211 {
212 case 3: // triangle
213 {
215 static const std::uint8_t fo = 4;
216 static const std::uint8_t map[3][2] =
217 {
218 {0, fo+0},
219 {fo+1, 0},
220 {0, fo+2}
221 };
222
223 return ScvfCornerStorage{ {p_[map[localScvfIdx][0]],
224 p_[map[localScvfIdx][1]]} };
225 }
226 case 4: // quadrilateral
227 {
229 static const std::uint8_t fo = 5;
230 static const std::uint8_t map[4][2] =
231 {
232 {fo+0, 0},
233 {0, fo+1},
234 {0, fo+2},
235 {fo+3, 0}
236 };
237
238 return ScvfCornerStorage{ {p_[map[localScvfIdx][0]],
239 p_[map[localScvfIdx][1]]} };
240 }
241 default:
242 DUNE_THROW(Dune::NotImplemented, "Box scvf geometries for dim=" << dim
243 << " dimWorld=" << dimWorld
244 << " corners=" << corners_);
245 }
246 }
247
249 ScvfCornerStorage getBoundaryScvfCorners(const Intersection& is,
250 const typename Intersection::Geometry& isGeom,
251 unsigned int indexInIntersection) const
252 {
253 const auto referenceElement = ReferenceElements::general(elementGeometry_.type());
254
255 const auto vIdxLocal = referenceElement.subEntity(is.indexInInside(), 1, indexInIntersection, dim);
256 if (indexInIntersection == 0)
257 return ScvfCornerStorage({p_[vIdxLocal+1], isGeom.center()});
258 else if (indexInIntersection == 1)
259 return ScvfCornerStorage({isGeom.center(), p_[vIdxLocal+1]});
260 else
261 DUNE_THROW(Dune::InvalidStateException, "local index exceeds the number of corners of 2d intersections");
262 }
263
265 template <int w = dimWorld>
266 typename std::enable_if<w == 3, GlobalPosition>::type
267 normal(const ScvfCornerStorage& scvfCorners,
268 const std::vector<unsigned int>& scvIndices) const
269 {
270 const auto v1 = elementGeometry_.corner(1) - elementGeometry_.corner(0);
271 const auto v2 = elementGeometry_.corner(2) - elementGeometry_.corner(0);
272 const auto v3 = Dumux::crossProduct(v1, v2);
273 const auto t = scvfCorners[1] - scvfCorners[0];
274 GlobalPosition normal = Dumux::crossProduct(v3, t);
275 normal /= normal.two_norm();
276
278 const auto v = elementGeometry_.corner(scvIndices[1]) - elementGeometry_.corner(scvIndices[0]);
279 const auto s = v*normal;
280 if (std::signbit(s))
281 normal *= -1;
282
283 return normal;
284 }
285
287 template <int w = dimWorld>
288 typename std::enable_if<w == 2, GlobalPosition>::type
289 normal(const ScvfCornerStorage& scvfCorners,
290 const std::vector<unsigned int>& scvIndices) const
291 {
293 const auto t = scvfCorners[1] - scvfCorners[0];
294 GlobalPosition normal({-t[1], t[0]});
295 normal /= normal.two_norm();
296
298 const auto v = elementGeometry_.corner(scvIndices[1]) - elementGeometry_.corner(scvIndices[0]);
299 const auto s = v*normal;
300 if (std::signbit(s))
301 normal *= -1;
302
303 return normal;
304 }
305
307 template <int w = dimWorld>
308 typename std::enable_if<w == 3, Scalar>::type
309 scvVolume(const ScvCornerStorage& p) const
310 {
311 return 0.5*Dumux::crossProduct(p[3]-p[0], p[2]-p[1]).two_norm();
312 }
313
315 template <int w = dimWorld>
316 typename std::enable_if<w == 2, Scalar>::type
317 scvVolume(const ScvCornerStorage& p) const
318 {
321 using std::abs;
322 return 0.5*abs(Dumux::crossProduct(p[3]-p[0], p[2]-p[1]));
323 }
324
326 Scalar scvfArea(const ScvfCornerStorage& p) const
327 {
328 return (p[1]-p[0]).two_norm();
329 }
330
331protected:
332 const typename Element::Geometry& elementGeometry_;
333 std::size_t corners_; // number of element corners
334 std::array<GlobalPosition, maxPoints> p_; // the points needed for construction of the geometries
335};
336
338template <class GridView, class ScvType, class ScvfType>
339class BoxGeometryHelper<GridView, 3, ScvType, ScvfType>
340{
341 using Scalar = typename GridView::ctype;
342 using GlobalPosition = typename Dune::FieldVector<Scalar, GridView::dimensionworld>;
343 using ScvCornerStorage = typename ScvType::Traits::CornerStorage;
344 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
345
346 using Element = typename GridView::template Codim<0>::Entity;
347 using Intersection = typename GridView::Intersection;
348
349 static constexpr auto dim = GridView::dimension;
350 static constexpr auto dimWorld = GridView::dimensionworld;
351 using ReferenceElements = typename Dune::ReferenceElements<Scalar, dim>;
352 using FaceReferenceElements = typename Dune::ReferenceElements<Scalar, dim-1>;
353
356 static constexpr int maxPoints = 27;
357public:
358 BoxGeometryHelper(const typename Element::Geometry& geometry)
359 : elementGeometry_(geometry)
360 , corners_(geometry.corners())
361 {
362 const auto referenceElement = ReferenceElements::general(geometry.type());
363
364 // the element center
365 p_[0] = geometry.center();
366
367 // vertices
368 for (int i = 0; i < corners_; ++i)
369 p_[i+1] = geometry.corner(i);
370
371 // edge midpoints
372 for (int i = 0; i < referenceElement.size(dim-1); ++i)
373 p_[i+corners_+1] = geometry.global(referenceElement.position(i, dim-1));
374
375 // face midpoints
376 for (int i = 0; i < referenceElement.size(1); ++i)
377 p_[i+corners_+1+referenceElement.size(dim-1)] = geometry.global(referenceElement.position(i, 1));
378 }
379
381 ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
382 {
383 // proceed according to number of corners of the element
384 switch (corners_)
385 {
386 case 4: // tetrahedron
387 {
389 static const std::uint8_t vo = 1;
390 static const std::uint8_t eo = 5;
391 static const std::uint8_t fo = 11;
392 static const std::uint8_t map[4][8] =
393 {
394 {vo+0, eo+0, eo+1, fo+0, eo+3, fo+1, fo+2, 0},
395 {vo+1, eo+2, eo+0, fo+0, eo+4, fo+3, fo+1, 0},
396 {vo+2, eo+1, eo+2, fo+0, eo+5, fo+2, fo+3, 0},
397 {vo+3, eo+3, eo+5, fo+2, eo+4, fo+1, fo+3, 0}
398 };
399
400 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
401 p_[map[localScvIdx][1]],
402 p_[map[localScvIdx][2]],
403 p_[map[localScvIdx][3]],
404 p_[map[localScvIdx][4]],
405 p_[map[localScvIdx][5]],
406 p_[map[localScvIdx][6]],
407 p_[map[localScvIdx][7]]} };
408 }
409 case 6: // prism
410 {
412 static const std::uint8_t vo = 1;
413 static const std::uint8_t eo = 7;
414 static const std::uint8_t fo = 16;
415 static const std::uint8_t map[6][8] =
416 {
417 {vo+0, eo+3, eo+4, fo+3, eo+0, fo+0, fo+1, 0},
418 {vo+1, eo+5, eo+3, fo+3, eo+1, fo+2, fo+0, 0},
419 {vo+2, eo+4, eo+5, fo+3, eo+2, fo+1, fo+2, 0},
420 {vo+3, eo+7, eo+6, fo+4, eo+0, fo+1, fo+0, 0},
421 {vo+4, eo+6, eo+8, fo+4, eo+1, fo+0, fo+2, 0},
422 {vo+5, eo+8, eo+7, fo+4, eo+2, fo+2, fo+1, 0}
423 };
424
425 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
426 p_[map[localScvIdx][1]],
427 p_[map[localScvIdx][2]],
428 p_[map[localScvIdx][3]],
429 p_[map[localScvIdx][4]],
430 p_[map[localScvIdx][5]],
431 p_[map[localScvIdx][6]],
432 p_[map[localScvIdx][7]]} };
433 }
434 case 8: // hexahedron
435 {
437 static const std::uint8_t vo = 1;
438 static const std::uint8_t eo = 9;
439 static const std::uint8_t fo = 21;
440 static const std::uint8_t map[8][8] =
441 {
442 {vo+0, eo+6, eo+4, fo+4, eo+0, fo+2, fo+0, 0},
443 {vo+1, eo+5, eo+6, fo+4, eo+1, fo+1, fo+2, 0},
444 {vo+2, eo+4, eo+7, fo+4, eo+2, fo+0, fo+3, 0},
445 {vo+3, eo+7, eo+5, fo+4, eo+3, fo+3, fo+1, 0},
446 {vo+4, eo+8, eo+10, fo+5, eo+0, fo+0, fo+2, 0},
447 {vo+5, eo+10, eo+9, fo+5, eo+1, fo+2, fo+1, 0},
448 {vo+6, eo+11, eo+8, fo+5, eo+2, fo+3, fo+0, 0},
449 {vo+7, eo+9, eo+11, fo+5, eo+3, fo+1, fo+3, 0},
450 };
451
452 return ScvCornerStorage{ {p_[map[localScvIdx][0]],
453 p_[map[localScvIdx][1]],
454 p_[map[localScvIdx][2]],
455 p_[map[localScvIdx][3]],
456 p_[map[localScvIdx][4]],
457 p_[map[localScvIdx][5]],
458 p_[map[localScvIdx][6]],
459 p_[map[localScvIdx][7]]} };
460 }
461 default:
462 DUNE_THROW(Dune::NotImplemented, "Box scv geometries for dim=" << dim
463 << " dimWorld=" << dimWorld
464 << " corners=" << corners_);
465 }
466 }
467
469 ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
470 {
471 // proceed according to number of corners of the element
472 switch (corners_)
473 {
474 case 4: // tetrahedron
475 {
477 static const std::uint8_t eo = 5;
478 static const std::uint8_t fo = 11;
479 static const std::uint8_t map[6][4] =
480 {
481 {eo+0, fo+0, fo+1, 0},
482 {fo+0, eo+1, 0, fo+2},
483 {eo+2, fo+0, fo+3, 0},
484 {fo+2, eo+3, 0, fo+1},
485 {fo+3, 0, eo+4, fo+1},
486 {eo+5, fo+2, fo+3, 0}
487 };
488
489 return ScvfCornerStorage{ {p_[map[localScvfIdx][0]],
490 p_[map[localScvfIdx][1]],
491 p_[map[localScvfIdx][2]],
492 p_[map[localScvfIdx][3]]} };
493 }
494 case 6: // prism
495 {
497 static const std::uint8_t eo = 7;
498 static const std::uint8_t fo = 16;
499 static const std::uint8_t map[9][4] =
500 {
501 {eo+0, fo+0, fo+1, 0},
502 {eo+1, fo+2, fo+0, 0},
503 {eo+2, fo+1, fo+2, 0},
504 {eo+3, fo+0, fo+3, 0},
505 {eo+4, fo+3, fo+1, 0},
506 {eo+5, fo+2, fo+3, 0},
507 {eo+6, fo+4, fo+0, 0},
508 {eo+7, fo+1, fo+4, 0},
509 {eo+8, fo+4, fo+2, 0}
510 };
511
512 return ScvfCornerStorage{ {p_[map[localScvfIdx][0]],
513 p_[map[localScvfIdx][1]],
514 p_[map[localScvfIdx][2]],
515 p_[map[localScvfIdx][3]]} };
516 }
517 case 8: // hexahedron
518 {
520 static const std::uint8_t eo = 9;
521 static const std::uint8_t fo = 21;
522 static const std::uint8_t map[12][4] =
523 {
524 {fo+0, eo+0, 0, fo+2},
525 {fo+1, 0, eo+1, fo+2},
526 {fo+3, eo+2, 0, fo+0},
527 {eo+3, fo+3, fo+1, 0},
528 {fo+4, eo+4, 0, fo+0},
529 {eo+5, fo+4, fo+1, 0},
530 {eo+6, fo+4, fo+2, 0},
531 {fo+4, eo+7, 0, fo+3},
532 { 0, fo+0, fo+5, eo+8},
533 {eo+9, fo+1, fo+5, 0},
534 {eo+10, fo+2, fo+5, 0},
535 {eo+11, fo+5, fo+3, 0}
536 };
537
538 return ScvfCornerStorage{ {p_[map[localScvfIdx][0]],
539 p_[map[localScvfIdx][1]],
540 p_[map[localScvfIdx][2]],
541 p_[map[localScvfIdx][3]]} };
542 }
543 default:
544 DUNE_THROW(Dune::NotImplemented, "Box scv geometries for dim=" << dim
545 << " dimWorld=" << dimWorld
546 << " corners=" << corners_);
547 }
548 }
549
551 ScvfCornerStorage getBoundaryScvfCorners(const Intersection& is,
552 const typename Intersection::Geometry& geometry,
553 unsigned int indexInIntersection) const
554 {
555 const auto referenceElement = ReferenceElements::general(elementGeometry_.type());
556 const auto faceRefElem = FaceReferenceElements::general(geometry.type());
557
558 GlobalPosition pi[9];
559 auto corners = geometry.corners();
560
561 // the facet center
562 pi[0] = geometry.center();
563
564 // corners
565 const auto idxInInside = is.indexInInside();
566 for (int i = 0; i < corners; ++i)
567 {
568 const auto vIdxLocal = referenceElement.subEntity(idxInInside, 1, i, dim);
569 pi[i+1] = elementGeometry_.corner(vIdxLocal);
570 }
571
572 // edge midpoints
573 for (int i = 0; i < faceRefElem.size(1); ++i)
574 {
575 const auto edgeIdxLocal = referenceElement.subEntity(idxInInside, 1, i, dim-1);
576 pi[i+corners+1] = p_[edgeIdxLocal+corners_+1];
577 }
578
579 // procees according to number of corners
580 switch (corners)
581 {
582 case 3: // triangle
583 {
585 static const std::uint8_t vo = 1;
586 static const std::uint8_t eo = 4;
587 static const std::uint8_t map[3][4] =
588 {
589 {vo+0, eo+0, eo+1, 0},
590 {vo+1, eo+2, eo+0, 0},
591 {vo+2, eo+1, eo+2, 0}
592 };
593
594 return ScvfCornerStorage{ {pi[map[indexInIntersection][0]],
595 pi[map[indexInIntersection][1]],
596 pi[map[indexInIntersection][2]],
597 pi[map[indexInIntersection][3]]} };
598 }
599 case 4: // quadrilateral
600 {
602 static const std::uint8_t vo = 1;
603 static const std::uint8_t eo = 5;
604 static const std::uint8_t map[4][4] =
605 {
606 {vo+0, eo+2, eo+0, 0},
607 {vo+1, eo+1, eo+2, 0},
608 {vo+2, eo+0, eo+3, 0},
609 {vo+3, eo+3, eo+1, 0}
610 };
611
612 return ScvfCornerStorage{ {pi[map[indexInIntersection][0]],
613 pi[map[indexInIntersection][1]],
614 pi[map[indexInIntersection][2]],
615 pi[map[indexInIntersection][3]]} };
616 }
617 default:
618 DUNE_THROW(Dune::NotImplemented, "Box scvf boundary geometries for dim=" << dim
619 << " dimWorld=" << dimWorld
620 << " corners=" << corners);
621 }
622 }
623
625 GlobalPosition normal(const ScvfCornerStorage& p,
626 const std::vector<unsigned int>& scvIndices) const
627 {
628 auto normal = Dumux::crossProduct(p[1]-p[0], p[2]-p[0]);
629 normal /= normal.two_norm();
630
631 const auto v = elementGeometry_.corner(scvIndices[1]) - elementGeometry_.corner(scvIndices[0]);
632 const auto s = v*normal;
633 if (std::signbit(s))
634 normal *= -1;
635
636 return normal;
637 }
638
640 Scalar scvVolume(const ScvCornerStorage& p) const
641 {
642 // after Grandy 1997, Efficient computation of volume of hexahedron
643 const auto v = p[7]-p[0];
644 return 1.0/6.0 * ( Dumux::tripleProduct(v, p[1]-p[0], p[3]-p[5])
645 + Dumux::tripleProduct(v, p[4]-p[0], p[5]-p[6])
646 + Dumux::tripleProduct(v, p[2]-p[0], p[6]-p[3]));
647 }
648
650 Scalar scvfArea(const ScvfCornerStorage& p) const
651 {
652 // after Wolfram alpha quadrilateral area
653 return 0.5*Dumux::crossProduct(p[3]-p[0], p[2]-p[1]).two_norm();
654 }
655
656protected:
657 const typename Element::Geometry& elementGeometry_;
658 std::size_t corners_; // number of element corners
659 std::array<GlobalPosition, maxPoints> p_; // the points needed for construction of the scv/scvf geometries
660};
661
662} // end namespace Dumux
663
664#endif
Define some often used mathematical functions.
Dune::FieldVector< Scalar, 3 > crossProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2)
Cross product of two vectors in three-dimensional Euclidean space.
Definition: math.hh:631
Scalar tripleProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2, const Dune::FieldVector< Scalar, 3 > &vec3)
Triple product of three vectors in three-dimensional Euclidean space retuning scalar.
Definition: math.hh:660
Definition: adapt.hh:29
Create sub control volumes and sub control volume face geometries.
Definition: boxgeometryhelper.hh:37
Scalar scvfArea(const ScvfCornerStorage &scvfCorners) const
get scvf area
Definition: boxgeometryhelper.hh:106
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition: boxgeometryhelper.hh:58
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: boxgeometryhelper.hh:63
std::array< GlobalPosition, maxPoints > p_
Definition: boxgeometryhelper.hh:114
GlobalPosition normal(const ScvfCornerStorage &scvfCorners, const std::vector< unsigned int > &scvIndices) const
get scvf normal vector
Definition: boxgeometryhelper.hh:91
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition: boxgeometryhelper.hh:77
ScvfCornerStorage getBoundaryScvfCorners(const Intersection &is, const typename Intersection::Geometry &geometry, unsigned int indexInIntersection) const
Create the sub control volume face geometries on the boundary.
Definition: boxgeometryhelper.hh:83
const Element::Geometry & elementGeometry_
Reference to the element geometry.
Definition: boxgeometryhelper.hh:112
Scalar scvVolume(const ScvCornerStorage &scvCorners) const
get scv volume
Definition: boxgeometryhelper.hh:100
std::size_t corners_
Definition: boxgeometryhelper.hh:113
std::enable_if< w==2, GlobalPosition >::type normal(const ScvfCornerStorage &scvfCorners, const std::vector< unsigned int > &scvIndices) const
get scvf normal vector for dim == 2, dimworld == 2
Definition: boxgeometryhelper.hh:289
Scalar scvfArea(const ScvfCornerStorage &p) const
get scvf area
Definition: boxgeometryhelper.hh:326
std::array< GlobalPosition, maxPoints > p_
Definition: boxgeometryhelper.hh:334
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the corners of sub control volume faces.
Definition: boxgeometryhelper.hh:207
const Element::Geometry & elementGeometry_
Reference to the element geometry.
Definition: boxgeometryhelper.hh:332
ScvfCornerStorage getBoundaryScvfCorners(const Intersection &is, const typename Intersection::Geometry &isGeom, unsigned int indexInIntersection) const
Create the sub control volume face geometries on the boundary.
Definition: boxgeometryhelper.hh:249
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition: boxgeometryhelper.hh:139
std::enable_if< w==3, Scalar >::type scvVolume(const ScvCornerStorage &p) const
get scv volume for dim == 2, dimworld == 3
Definition: boxgeometryhelper.hh:309
std::size_t corners_
Definition: boxgeometryhelper.hh:333
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: boxgeometryhelper.hh:158
std::enable_if< w==2, Scalar >::type scvVolume(const ScvCornerStorage &p) const
get scv volume for dim == 2, dimworld == 2
Definition: boxgeometryhelper.hh:317
std::enable_if< w==3, GlobalPosition >::type normal(const ScvfCornerStorage &scvfCorners, const std::vector< unsigned int > &scvIndices) const
get scvf normal vector for dim == 2, dimworld == 3
Definition: boxgeometryhelper.hh:267
Scalar scvfArea(const ScvfCornerStorage &p) const
get scvf area
Definition: boxgeometryhelper.hh:650
const Element::Geometry & elementGeometry_
Reference to the element geometry.
Definition: boxgeometryhelper.hh:657
GlobalPosition normal(const ScvfCornerStorage &p, const std::vector< unsigned int > &scvIndices) const
get scvf normal vector
Definition: boxgeometryhelper.hh:625
std::array< GlobalPosition, maxPoints > p_
Definition: boxgeometryhelper.hh:659
BoxGeometryHelper(const typename Element::Geometry &geometry)
Definition: boxgeometryhelper.hh:358
Scalar scvVolume(const ScvCornerStorage &p) const
get scv volume
Definition: boxgeometryhelper.hh:640
ScvCornerStorage getScvCorners(unsigned int localScvIdx) const
Create a vector with the scv corners.
Definition: boxgeometryhelper.hh:381
ScvfCornerStorage getBoundaryScvfCorners(const Intersection &is, const typename Intersection::Geometry &geometry, unsigned int indexInIntersection) const
Create the sub control volume face geometries on the boundary.
Definition: boxgeometryhelper.hh:551
std::size_t corners_
Definition: boxgeometryhelper.hh:658
ScvfCornerStorage getScvfCorners(unsigned int localScvfIdx) const
Create a vector with the scvf corners.
Definition: boxgeometryhelper.hh:469