Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
fv_util.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2021: G-CSC, Goethe University Frankfurt
3 * Authors: Andreas Vogel, Dmitrij Logashenko, Martin Stepniewski
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_VOLUME_UTIL__
34#define __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_VOLUME_UTIL__
35
36// extern libraries
37#include <cmath>
38#include <vector>
39
40// other ug4 modules
41#include "common/common.h"
42
46
47namespace ug{
48
50
58template <typename TPosition>
59void AveragePositions(TPosition& vOut, const TPosition* vCornerCoords, size_t num)
60{
61 vOut = vCornerCoords[0];
62 for(size_t j = 1; j < num; ++j)
63 {
64 vOut += vCornerCoords[j];
65 }
66 vOut *= 1./(number)num;
67}
68
69
70
72// Finite Volume Traits
74
76template <typename TRefElem> struct fv1_traits_most_common
77{
79 typedef TRefElem ref_elem_type;
80
82 static const size_t numSCV = ref_elem_type::numCorners;
83
85 static const size_t numSCVF = ref_elem_type::numEdges;
86
88 static size_t scvf_from_to
89 (
90 const ref_elem_type& refElem,
91 size_t i,
92 size_t ft
93 )
94 {
95 return refElem.id(1, i, 0, ft);
96 }
97
99 static size_t scv_node_id
100 (
101 const ref_elem_type& refElem,
102 size_t i
103 )
104 {
105 return i;
106 }
107
109 static void scvf_mid_id
110 (
111 const ref_elem_type& refElem,
112 MidID *vMidID,
113 size_t i
114 )
115 {
116 static const int dim = TRefElem::dim;
117
118 // set mid ids:
119
120 // start at edge midpoint
121 vMidID[0] = MidID(1,i);
122
123 // loop up dimension
124 if(dim == 2)
125 {
126 vMidID[1] = MidID(dim, 0); // center of element
127 }
128 else if (dim == 3)
129 {
130 vMidID[1] = MidID(2, refElem.id(1, i, 2, 0)); // side 0
131 vMidID[2] = MidID(dim, 0); // center of element
132 vMidID[3] = MidID(2, refElem.id(1, i, 2, 1)); // side 1
133 }
134 }
135
137 static void scv_mid_id
138 (
139 const ref_elem_type& refElem,
140 MidID *vMidID,
141 size_t i
142 )
143 {
144 static const int dim = TRefElem::dim;
145
146 // set mid ids:
147
148 if(dim == 1)
149 {
150 vMidID[0] = MidID(0, i); // set node as corner of scv
151 vMidID[1] = MidID(dim, 0); // center of element
152 }
153 else if(dim == 2)
154 {
155 vMidID[0] = MidID(0, i); // set node as corner of scv
156 vMidID[1] = MidID(1, refElem.id(0, i, 1, 0)); // edge 1
157 vMidID[2] = MidID(dim, 0); // center of element
158 vMidID[3] = MidID(1, refElem.id(0, i, 1, 1)); // edge 2
159 }
160 else if(dim == 3)
161 {
162 vMidID[0] = MidID(0, i); // set node as corner of scv
163 vMidID[1] = MidID(1, refElem.id(0, i, 1, 1)); // edge 1
164 vMidID[2] = MidID(2, refElem.id(0, i, 2, 0)); // face 0
165 vMidID[3] = MidID(1, refElem.id(0, i, 1, 0)); // edge 0
166 vMidID[4] = MidID(1, refElem.id(0, i, 1, 2)); // edge 2
167 vMidID[5] = MidID(2, refElem.id(0, i, 2, 2)); // face 2
168 vMidID[6] = MidID(dim, 0); // center of element
169 vMidID[7] = MidID(2, refElem.id(0, i, 2, 1)); // face 1
170 }
171 else {UG_THROW("Dimension higher than 3 not implemented.");}
172 }
173};
174
176template <typename TRefElem, int TWorldDim> struct fv1_traits
177: public fv1_traits_most_common<TRefElem>
178{
179// maximum for dimension
180 static const size_t maxNumSCVF;
181 static const size_t maxNumSCV;
182 static const size_t maxNSH;
183
184// number of corners of scvf
185 const static size_t NumCornersOfSCVF;
186
187// maximum of corners of scv
188 const static size_t NumCornersOfSCV;
189
190// maximum of corners of bf
191 const static size_t NumCornersOfBF;
192
193// computes the normal to a scvf
194 static void NormalOnSCVF(MathVector<TWorldDim>& outNormal,
195 const MathVector<TWorldDim>* vSCVFCorner,
196 const MathVector<TWorldDim>* vElemCorner);
197
198// computes the normal to a bf
199 static void NormalOnBF(MathVector<TWorldDim>& outNormal,
200 const MathVector<TWorldDim>* vSCVFCorner,
201 const MathVector<TWorldDim>* vElemCorner);
202
203// types of scv and scvf and bf
204 typedef void scv_type;
205 typedef void scvf_type;
206 typedef void bf_type;
207};
208
210// 1D Reference Element
212
214{
215 static const size_t maxNumSCVF = 1;
216 static const size_t maxNumSCV = 2;
217 static const size_t maxNSH = maxNumSCV;
218
219 const static size_t NumCornersOfSCVF = 1;
220 const static size_t NumCornersOfSCV = 2;
221 const static size_t NumCornersOfBF = 1;
222
226};
227
228template <> struct fv1_traits<ReferenceEdge, 1>
230 public fv1_traits_most_common<ReferenceEdge>
231{
232 static void NormalOnSCVF(MathVector<1>& outNormal,
233 const MathVector<1>* vSCVFCorner,
234 const MathVector<1>* vElemCorner)
235 {
236 ElementNormal<ReferenceVertex, 1>(outNormal, vSCVFCorner);
237 VecNormalize(outNormal, outNormal);
238 }
239 static void NormalOnBF(MathVector<1>& outNormal,
240 const MathVector<1>* vSCVFCorner,
241 const MathVector<1>* vElemCorner)
242 {
243 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
244 }
245};
246
247template <> struct fv1_traits<ReferenceEdge, 2>
249 public fv1_traits_most_common<ReferenceEdge>
250{
251 static void NormalOnSCVF(MathVector<2>& outNormal,
252 const MathVector<2>* vSCVFCorner,
253 const MathVector<2>* vElemCorner)
254 {
255 VecSubtract(outNormal, vElemCorner[1], vElemCorner[0]);
256 VecNormalize(outNormal, outNormal);
257 }
258 static void NormalOnBF(MathVector<2>& outNormal,
259 const MathVector<2>* vSCVFCorner,
260 const MathVector<2>* vElemCorner)
261 {
262 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
263 }
264};
265
266template <> struct fv1_traits<ReferenceEdge, 3>
268 public fv1_traits_most_common<ReferenceEdge>
269{
270 static void NormalOnSCVF(MathVector<3>& outNormal,
271 const MathVector<3>* vSCVFCorner,
272 const MathVector<3>* vElemCorner)
273 {
274 VecSubtract(outNormal, vElemCorner[1], vElemCorner[0]);
275 VecNormalize(outNormal, outNormal);
276 }
277 static void NormalOnBF(MathVector<3>& outNormal,
278 const MathVector<3>* vSCVFCorner,
279 const MathVector<3>* vElemCorner)
280 {
281 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
282 }
283};
284
286// 2D Reference Element
288
290{
291 static const size_t maxNumSCVF = 4;
292 static const size_t maxNumSCV = 4;
293 static const size_t maxNSH = maxNumSCV;
294
295 const static size_t NumCornersOfSCVF = 2;
296 const static size_t NumCornersOfSCV = 4;
297 const static size_t NumCornersOfBF = 2;
298
302};
303
305{
306 static void NormalOnSCVF(MathVector<2>& outNormal,
307 const MathVector<2>* vSCVFCorner,
308 const MathVector<2>* vElemCorner)
309 {ElementNormal<ReferenceEdge, 2>(outNormal, vSCVFCorner);}
310 static void NormalOnBF(MathVector<2>& outNormal,
311 const MathVector<2>* vSCVFCorner,
312 const MathVector<2>* vElemCorner)
313 {
314 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
315 }
316};
317
319{
320 template <typename TElem>
321 static void NormalOnSCVF_Face(MathVector<3>& outNormal,
322 const MathVector<3>* vSCVFCorner,
323 const MathVector<3>* vElemCorner)
324 {
325 // compute Normal to Face (right-handed)
326 MathVector<3> ElemNormal;
327 ElementNormal<TElem,3>(ElemNormal, vElemCorner);
328
329 // compute a Point such that the triangle given by vSCVFCorner and p
330 // has the following property:
331 // a) The new Triangle is normal to the ElementFace
332 // b) The new Triangle contains the scvf
334 VecAdd(p, vSCVFCorner[0], ElemNormal);
335
336 MathVector<3> vNewTriangleCorner[3];
337 vNewTriangleCorner[0] = vSCVFCorner[0];
338 vNewTriangleCorner[1] = vSCVFCorner[1];
339 vNewTriangleCorner[2] = p;
340
341 // now compute Normal to new triangle. This Normal will be normal to
342 // the scvf and within the original element
343 ElementNormal<ReferenceTriangle, 3>(outNormal, vNewTriangleCorner);
344
345 // scale to normal to the size of the scvf
346 const number size = VecDistance(vSCVFCorner[0], vSCVFCorner[1]);
347 VecNormalize(outNormal, outNormal);
348 VecScale(outNormal, outNormal, size);
349 }
350 static void NormalOnSCVF(MathVector<3>& outNormal,
351 const MathVector<3>* vSCVFCorner,
352 const MathVector<3>* vElemCorner)
353 {
354 UG_THROW("not implemented.")
355 }
356 static void NormalOnBF(MathVector<3>& outNormal,
357 const MathVector<3>* vSCVFCorner,
358 const MathVector<3>* vElemCorner)
359 {
360 UG_THROW("not implemented.")
361 }
362};
363
364template <> struct fv1_traits<ReferenceTriangle, 2>
366 public fv1_traits_most_common<ReferenceTriangle>
367{};
368template <> struct fv1_traits<ReferenceTriangle, 3>
370 public fv1_traits_most_common<ReferenceTriangle>
371{
372 static void NormalOnSCVF(MathVector<3>& outNormal,
373 const MathVector<3>* vSCVFCorner,
374 const MathVector<3>* vElemCorner)
375 {fv1_traits_ReferenceFace3d::NormalOnSCVF_Face<ReferenceTriangle>(outNormal, vSCVFCorner, vElemCorner);}
376 static void NormalOnBF(MathVector<3>& outNormal,
377 const MathVector<3>* vSCVFCorner,
378 const MathVector<3>* vElemCorner)
379 {
380 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
381 }
382};
383
384template <> struct fv1_traits<ReferenceQuadrilateral, 2>
386 public fv1_traits_most_common<ReferenceQuadrilateral>
387{};
388template <> struct fv1_traits<ReferenceQuadrilateral, 3>
390 public fv1_traits_most_common<ReferenceQuadrilateral>
391{
392 static void NormalOnSCVF(MathVector<3>& outNormal,
393 const MathVector<3>* vSCVFCorner,
394 const MathVector<3>* vElemCorner)
395 {fv1_traits_ReferenceFace3d::NormalOnSCVF_Face<ReferenceQuadrilateral>(outNormal, vSCVFCorner, vElemCorner);}
396 static void NormalOnBF(MathVector<3>& outNormal,
397 const MathVector<3>* vSCVFCorner,
398 const MathVector<3>* vElemCorner)
399 {
400 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
401 }
402};
403
405// 3D Reference Element
407
409{
410 static const size_t maxNumSCVF = 24;
411 static const size_t maxNumSCV = 32;
412 static const size_t maxNSH = 8;
413
414 const static size_t NumCornersOfSCVF = 4;
415 const static size_t NumCornersOfSCV = 8;
416 const static size_t NumCornersOfBF = 4;
417
421
422 static void NormalOnSCVF(MathVector<3>& outNormal,
423 const MathVector<3>* vSCVFCorner,
424 const MathVector<3>* vElemCorner)
425 {ElementNormal<ReferenceQuadrilateral, 3>(outNormal, vSCVFCorner);}
426 static void NormalOnBF(MathVector<3>& outNormal,
427 const MathVector<3>* vSCVFCorner,
428 const MathVector<3>* vElemCorner)
429 {
430 NormalOnSCVF(outNormal, vSCVFCorner, vElemCorner);
431 }
432};
433
434template <> struct fv1_traits<ReferenceTetrahedron, 3>
436 public fv1_traits_most_common<ReferenceTetrahedron>
437{};
438template <> struct fv1_traits<ReferencePrism, 3>
440 public fv1_traits_most_common<ReferencePrism>
441{};
442template <> struct fv1_traits<ReferenceHexahedron, 3>
444 public fv1_traits_most_common<ReferenceHexahedron>
445{};
446
448
454 // Remark: Pyramid is a special case, fv1_traits_most_common<ReferencePyramid> is not inherited here!
455{
456 static const size_t numSCV = 4 * ReferencePyramid::numEdges;
457
458 static const size_t numSCVF = 2 * ReferencePyramid::numEdges;
459
460 const static size_t NumCornersOfSCVF = 3; // triangles
461 const static size_t NumCornersOfSCV = 4; // tetrahedrons
462 const static size_t NumCornersOfBF = 4; // quadrilaterals
463
467
469 static size_t scvf_from_to
470 (
471 const ReferencePyramid& refElem,
472 size_t i,
473 size_t ft
474 )
475 { // map according to the order defined in ComputeSCVFMidID
476 return refElem.id(1, i/2, 0, ft);
477 }
478
480 static size_t scv_node_id
481 (
482 const ReferencePyramid& refElem,
483 size_t i
484 )
485 { // map according to order defined in ComputeSCVMidID
486 if(i%2 == 0){
487 return refElem.id(1, i/4, 0, 0); // from
488 } else {
489 return refElem.id(1, i/4, 0, 1); // to
490 }
491 }
492
494 static void scvf_mid_id
495 (
496 const ReferencePyramid& refElem,
497 MidID *vMidID,
498 size_t i
499 )
500 {
501 static const int dim = 3;
502
503 // set mid ids:
504
505 // start at edge midpoint
506 vMidID[0] = MidID(1,i/2);
507
508 // there are 2 scvf per edge
509 if(i%2 == 0){
510 vMidID[1] = MidID(2, refElem.id(1, i/2, 2, 0)); // side 0
511 vMidID[2] = MidID(dim, 0); // center of element
512 } else {
513 vMidID[1] = MidID(dim, 0); // center of element
514 vMidID[2] = MidID(2, refElem.id(1, i/2, 2, 1)); // side 1
515 }
516 }
517
519 static void scv_mid_id
520 (
521 const ReferencePyramid& refElem,
522 MidID *vMidID,
523 size_t i
524 )
525 {
526 static const int dim = 3;
527
528 // set mid ids:
529
530 // start at edge midpoint
531 vMidID[3] = MidID(1,i/4);
532
533 // there are 2 scvf per edge
534 if(i%4 == 0 || i%4 == 1){
535 vMidID[1] = MidID(2, refElem.id(1, i/4, 2, 0)); // side 0
536 vMidID[2] = MidID(dim, 0); // center of element
537 } else {
538 vMidID[1] = MidID(dim, 0); // center of element
539 vMidID[2] = MidID(2, refElem.id(1, i/4, 2, 1)); // side 1
540 }
541
542 // connect to from / to corners of edge
543 if(i%2 == 0){
544 vMidID[0] = MidID(0, refElem.id(1, i/4, 0, 0)); // from
545 } else {
546 vMidID[0] = MidID(0, refElem.id(1, i/4, 0, 1)); // to
547 }
548 }
549};
551
556{
557 static void NormalOnSCVF(MathVector<3>& outNormal,
558 const MathVector<3>* vSCVFCorner,
559 const MathVector<3>* vElemCorner)
560 {ElementNormal<ReferenceTriangle, 3>(outNormal, vSCVFCorner);}
561 static void NormalOnBF(MathVector<3>& outNormal,
562 const MathVector<3>* vSCVFCorner,
563 const MathVector<3>* vElemCorner)
564 {
565 ElementNormal<ReferenceQuadrilateral, 3>(outNormal, vSCVFCorner);
566 }
567};
568
572 // Remark: Octahedron is a special case, fv1_traits_most_common<ReferenceOctahedron> is not inherited here!
573{
582 static const size_t numSCV = 16;
583
584 static const size_t numSCVF = 24;
585 // Remark: Special case for octahedron, scvf not mappable by edges.
586
587// maximum dimension of substructure objects
588 enum{MAXDIM = 3};
589
590// maximum number of substructure objects
592
593// maximum number of substructure corners
595
597
611 static int substruct_coID(int dim_i, size_t i, size_t j)
612 {
613 // Corner indices of implicit interior substructure Geometric Objects
615
616 // subedge 0 = (3,1)
617 substruct_coID[EDGE][0][0] = 3;
618 substruct_coID[EDGE][0][1] = 1;
619 // subedge 1 = (1,3)
620 substruct_coID[EDGE][1][0] = 1;
621 substruct_coID[EDGE][1][1] = 3;
622
623 // subface 0 = (1,2,3)
624 substruct_coID[FACE][0][0] = 1;
625 substruct_coID[FACE][0][1] = 2;
626 substruct_coID[FACE][0][2] = 3;
627 // subface 1 = (1,3,2)
628 substruct_coID[FACE][1][0] = 1;
629 substruct_coID[FACE][1][1] = 3;
630 substruct_coID[FACE][1][2] = 2;
631 // subface 2 = (1,3,4)
632 substruct_coID[FACE][2][0] = 1;
633 substruct_coID[FACE][2][1] = 3;
634 substruct_coID[FACE][2][2] = 4;
635 // subface 3 = (1,4,3)
636 substruct_coID[FACE][3][0] = 1;
637 substruct_coID[FACE][3][1] = 4;
638 substruct_coID[FACE][3][2] = 3;
639 // subface 4 = (1,3,5)
640 substruct_coID[FACE][4][0] = 1;
641 substruct_coID[FACE][4][1] = 3;
642 substruct_coID[FACE][4][2] = 5;
643 // subface 5 = (1,5,3)
644 substruct_coID[FACE][5][0] = 1;
645 substruct_coID[FACE][5][1] = 5;
646 substruct_coID[FACE][5][2] = 3;
647 // subface 6 = (1,0,3)
648 substruct_coID[FACE][6][0] = 1;
649 substruct_coID[FACE][6][1] = 0;
650 substruct_coID[FACE][6][2] = 3;
651 // subface 7 = (1,0,3)
652 substruct_coID[FACE][7][0] = 1;
653 substruct_coID[FACE][7][1] = 3;
654 substruct_coID[FACE][7][2] = 0;
655
656 // subvolume 0 = (1,2,3,5)
657 substruct_coID[VOLUME][0][0] = 1;
658 substruct_coID[VOLUME][0][1] = 2;
659 substruct_coID[VOLUME][0][2] = 3;
660 substruct_coID[VOLUME][0][3] = 5;
661 // subvolume 1 = (1,3,4,5)
662 substruct_coID[VOLUME][1][0] = 1;
663 substruct_coID[VOLUME][1][1] = 3;
664 substruct_coID[VOLUME][1][2] = 4;
665 substruct_coID[VOLUME][1][3] = 5;
666 // subvolume 2 = (1,2,3,0)
667 substruct_coID[VOLUME][2][0] = 1;
668 substruct_coID[VOLUME][2][1] = 2;
669 substruct_coID[VOLUME][2][2] = 3;
670 substruct_coID[VOLUME][2][3] = 0;
671 // subvolume 3 = (1,3,4,0)
672 substruct_coID[VOLUME][3][0] = 1;
673 substruct_coID[VOLUME][3][1] = 3;
674 substruct_coID[VOLUME][3][2] = 4;
675 substruct_coID[VOLUME][3][3] = 0;
676
677 return substruct_coID[dim_i][i][j];
678 }
679
681
691 static size_t substruct_num(int dim)
692 {
693 // number of interior substructure Geometric Objects
694 size_t vSubStructNum[MAXDIM+1];
695
696 vSubStructNum[VERTEX] = 0; // no additional vertices in the substructure
697 vSubStructNum[EDGE] = 2;
698 vSubStructNum[FACE] = 8;
699 vSubStructNum[VOLUME] = 4;
700
701 return vSubStructNum[dim];
702 }
703
705
719 static size_t substruct_num(int dim_i, size_t i, int dim_j)
720 {
721 // number of interior substructure Geometric Objects
722 size_t vSubStructSubNum[MAXDIM+1][MAXSUBSTRUCTOBJECTS][MAXDIM+1];
723
724 for(size_t i = 0; i < substruct_num(VOLUME); ++i)
725 {
726 vSubStructSubNum[VOLUME][i][VERTEX] = 4;
727 vSubStructSubNum[VOLUME][i][EDGE] = 6;
728 vSubStructSubNum[VOLUME][i][FACE] = 4;
729 vSubStructSubNum[VOLUME][i][VOLUME] = 1;
730 }
731
732 for(size_t i = 0; i < substruct_num(FACE); ++i)
733 {
734 vSubStructSubNum[FACE][i][VERTEX] = 3;
735 vSubStructSubNum[FACE][i][EDGE] = 3;
736 vSubStructSubNum[FACE][i][FACE] = 1;
737 vSubStructSubNum[FACE][i][VOLUME] = 1;
738 }
739
740 for(size_t i = 0; i < substruct_num(EDGE); ++i)
741 {
742 vSubStructSubNum[EDGE][i][VERTEX] = 2;
743 vSubStructSubNum[EDGE][i][EDGE] = 1;
744 vSubStructSubNum[EDGE][i][FACE] = 2;
745 vSubStructSubNum[EDGE][i][VOLUME] = 1;
746 }
747
748 for(size_t i = 0; i < substruct_num(VERTEX); ++i)
749 {
750 vSubStructSubNum[VERTEX][i][VERTEX] = 1;
751 vSubStructSubNum[VERTEX][i][EDGE] = 3;
752 vSubStructSubNum[VERTEX][i][FACE] = 3;
753 vSubStructSubNum[VERTEX][i][VOLUME] = 1;
754 }
755
756 return vSubStructSubNum[dim_i][i][dim_j];
757 }
758
760 static size_t scvf_from_to
761 (
762 const ReferenceOctahedron& refElem,
763 size_t i,
764 size_t ft
765 )
766 { // map according to the order defined in ComputeSCVFMidID
767 static size_t from_to_ind [24][2] =
768 {
769 {1, 2}, // face 0
770 {2, 1}, // face 1
771
772 {2, 3}, // face 2
773 {3, 2}, // face 3
774
775 {3, 1}, // face 4
776 {1, 3}, // face 5
777
778 {1, 5}, // face 6
779 {1, 0}, // face 7
780
781 {2, 5}, // face 8
782 {2, 0}, // face 9
783
784 {3, 5}, // face 10
785 {3, 0}, // face 11
786
787 {1, 3}, // face 12
788 {3, 1}, // face 13
789
790 {3, 4}, // face 14
791 {4, 3}, // face 15
792
793 {4, 1}, // face 16
794 {1, 4}, // face 17
795
796 {1, 5}, // face 18
797 {1, 0}, // face 19
798
799 {3, 5}, // face 20
800 {3, 0}, // face 21
801
802 {4, 5}, // face 22
803 {4, 0} // face 23
804 };
805 return from_to_ind [i] [ft];
806 }
807
809 static size_t scv_node_id
810 (
811 const ReferenceOctahedron& refElem,
812 size_t i
813 )
814 { // map according to order defined in ComputeSCVMidID
815 static size_t node_id [16] =
816 {
817 1, // scv 0
818 1, // scv 1
819
820 2, // scv 2
821 2, // scv 3
822
823 3, // scv 4
824 3, // scv 5
825
826 5, // scv 6
827 0, // scv 7
828
829 1, // scv 8
830 1, // scv 9
831
832 3, // scv 10
833 3, // scv 11
834
835 4, // scv 12
836 4, // scv 13
837
838 5, // scv 14
839 0 // scv 15
840 };
841 return node_id [i];
842 }
843
845 static void scvf_mid_id
846 (
847 const ReferenceOctahedron& refElem,
848 MidID *vMidID,
849 size_t i
850 )
851 {
852 switch (i)
853 {
854 // scvf of edge 4 (top)
855 case 0: vMidID[0] = MidID(1,4); // edge 4
856 vMidID[1] = MidID(2,8); // subface 0 = 1,2,3
857 vMidID[2] = MidID(3,1); // subvolume 0
858 vMidID[3] = MidID(2,4); // face 4
859 break;
860 // scvf of edge 4 (bottom)
861 case 1: vMidID[0] = MidID(1,4); // edge 4
862 vMidID[1] = MidID(2,9); // subface 1 = 1,3,2
863 vMidID[2] = MidID(3,3); // subvolume 2
864 vMidID[3] = MidID(2,0); // face 0
865 break;
866
867
868 // scvf of edge 5 (top)
869 case 2: vMidID[0] = MidID(1,5); // edge 5
870 vMidID[1] = MidID(2,8); // subface 0 = 1,2,3
871 vMidID[2] = MidID(3,1); // subvolume 0
872 vMidID[3] = MidID(2,5); // face 5
873 break;
874 // scvf of edge 5 (bottom)
875 case 3: vMidID[0] = MidID(1,5); // edge 5
876 vMidID[1] = MidID(2,9); // subface 1 = 1,3,2
877 vMidID[2] = MidID(3,3); // subvolume 2
878 vMidID[3] = MidID(2,1); // face 1
879 break;
880
881
882 // scvf of diagonal 3->1 (top) in subvolume 0
883 case 4: vMidID[0] = MidID(1,12);// diagonal 3->1
884 vMidID[1] = MidID(2,8); // subface 0 = 1,2,3
885 vMidID[2] = MidID(3,1); // subvolume 0
886 vMidID[3] = MidID(2,13);// face 1,5,3
887 break;
888 // scvf of diagonal 1->3 (bottom) in subvolume 2
889 case 5: vMidID[0] = MidID(1,13);// diagonal 1->3
890 vMidID[1] = MidID(2,9); // subface 1 = 1,3,2
891 vMidID[2] = MidID(3,3); // subvolume 2
892 vMidID[3] = MidID(2,14);// face 1,0,3
893 break;
894
895
896 // scvf of edge 8 in subvolume 0
897 case 6: vMidID[0] = MidID(1,8); // edge 8
898 vMidID[1] = MidID(2,4); // face 4
899 vMidID[2] = MidID(3,1); // subvolume 0
900 vMidID[3] = MidID(2,13);// face 1,5,3
901 break;
902 // scvf of edge 0 in subvolume 2
903 case 7: vMidID[0] = MidID(1,0); // edge 0
904 vMidID[1] = MidID(2,15);// face 1,3,0
905 vMidID[2] = MidID(3,3); // subvolume 2
906 vMidID[3] = MidID(2,0); // face 0
907 break;
908
909
910 // scvf of edge 9 in subvolume 0
911 case 8: vMidID[0] = MidID(1,9); // edge 9
912 vMidID[1] = MidID(2,5); // face 5
913 vMidID[2] = MidID(3,1); // subvolume 0
914 vMidID[3] = MidID(2,4); // face 4
915 break;
916 // scvf of edge 1 in subvolume 2
917 case 9: vMidID[0] = MidID(1,1); // edge 1
918 vMidID[1] = MidID(2,0); // face 0
919 vMidID[2] = MidID(3,3); // subvolume 2
920 vMidID[3] = MidID(2,1); // face 1
921 break;
922
923
924 // scvf of edge 10 in subvolume 0
925 case 10:vMidID[0] = MidID(1,10);// edge 10
926 vMidID[1] = MidID(2,12);// face 1,3,5
927 vMidID[2] = MidID(3,1); // subvolume 0
928 vMidID[3] = MidID(2,5); // face 5
929 break;
930 // scvf of edge 2 in subvolume 2
931 case 11:vMidID[0] = MidID(1,2); // edge 2
932 vMidID[1] = MidID(2,1); // face 1
933 vMidID[2] = MidID(3,3); // subvolume 2
934 vMidID[3] = MidID(2,14);// face 1,0,3
935 break;
936
937
938 // scvf of diagonal 1->3 (top) in subvolume 1
939 case 12:vMidID[0] = MidID(1,13);// diagonal 1->3
940 vMidID[1] = MidID(2,10);// subface 2 = 1,3,4
941 vMidID[2] = MidID(3,2); // subvolume 1
942 vMidID[3] = MidID(2,12);// face 1,3,5
943 break;
944 // scvf of diagonal 3->1 (bottom) in subvolume 3
945 case 13:vMidID[0] = MidID(1,12);// diagonal 3->1
946 vMidID[1] = MidID(2,11);// subface 3 = 1,4,3
947 vMidID[2] = MidID(3,4); // subvolume 3
948 vMidID[3] = MidID(2,15);// face 1,3,0
949 break;
950
951
952 // scvf of edge 6 (top)
953 case 14:vMidID[0] = MidID(1,6); // edge 6
954 vMidID[1] = MidID(2,10);// subface 2 = 1,3,4
955 vMidID[2] = MidID(3,2); // subvolume 1
956 vMidID[3] = MidID(2,6); // face 6
957 break;
958 // scvf of edge 6 (bottom)
959 case 15:vMidID[0] = MidID(1,6); // edge 6
960 vMidID[1] = MidID(2,11);// subface 3 = 1,4,3
961 vMidID[2] = MidID(3,4); // subvolume 3
962 vMidID[3] = MidID(2,2); // face 2
963 break;
964
965
966 // scvf of edge 7 (top)
967 case 16:vMidID[0] = MidID(1,7); // edge 7
968 vMidID[1] = MidID(2,10);// subface 2 = 1,3,4
969 vMidID[2] = MidID(3,2); // subvolume 1
970 vMidID[3] = MidID(2,7); // face 7
971 break;
972 // scvf of edge 7 (bottom)
973 case 17:vMidID[0] = MidID(1,7); // edge 7
974 vMidID[1] = MidID(2,11);// subface 3 = 1,4,3
975 vMidID[2] = MidID(3,4); // subvolume 3
976 vMidID[3] = MidID(2,3); // face 3
977 break;
978
979
980 // scvf of edge 8 in subvolume 1
981 case 18:vMidID[0] = MidID(1,8); // edge 8
982 vMidID[1] = MidID(2,13);// face 1,5,3
983 vMidID[2] = MidID(3,2); // subvolume 1
984 vMidID[3] = MidID(2,7); // face 7
985 break;
986 // scvf of edge 0 in subvolume 3
987 case 19:vMidID[0] = MidID(1,0); // edge 0
988 vMidID[1] = MidID(2,3); // face 3
989 vMidID[2] = MidID(3,4); // subvolume 3
990 vMidID[3] = MidID(2,15);// face 1,3,0
991 break;
992
993
994 // scvf of edge 10 in subvolume 1
995 case 20:vMidID[0] = MidID(1,10);// edge 10
996 vMidID[1] = MidID(2,6); // face 6
997 vMidID[2] = MidID(3,2); // subvolume 1
998 vMidID[3] = MidID(2,12);// face 1,3,5
999 break;
1000 // scvf of edge 2 in subvolume 3
1001 case 21:vMidID[0] = MidID(1,2); // edge 2
1002 vMidID[1] = MidID(2,14);// face 1,0,3
1003 vMidID[2] = MidID(3,4); // subvolume 3
1004 vMidID[3] = MidID(2,2); // face 2
1005 break;
1006
1007
1008 // scvf of edge 11 in subvolume 1
1009 case 22:vMidID[0] = MidID(1,11);// edge 11
1010 vMidID[1] = MidID(2,7); // face 7
1011 vMidID[2] = MidID(3,2); // subvolume 1
1012 vMidID[3] = MidID(2,6); // face 6
1013 break;
1014 // scvf of edge 3 in subvolume 3
1015 case 23:vMidID[0] = MidID(1,3); // edge 3
1016 vMidID[1] = MidID(2,2); // face 2
1017 vMidID[2] = MidID(3,4); // subvolume 3
1018 vMidID[3] = MidID(2,3); // face 3
1019 break;
1020
1021
1022 default:UG_THROW("Octahedron only has 24 SCVFs (no. 0-23), but requested no. " << i << ".");
1023 break;
1024 }
1025 }
1026
1028 static void scv_mid_id
1029 (
1030 const ReferenceOctahedron& refElem,
1031 MidID *vMidID,
1032 size_t i
1033 )
1034 {
1035 switch (i)
1036 {
1037 // scv of corner 1 in subvolume 0 (top)
1038 case 0: vMidID[0] = MidID(0,1); // corner 1
1039 vMidID[1] = MidID(1,4); // edge 4
1040 vMidID[2] = MidID(2,8); // subface 0 = 1,2,3
1041 vMidID[3] = MidID(1,12);// edge 3->1
1042 vMidID[4] = MidID(1,8); // edge 8
1043 vMidID[5] = MidID(2,4); // face 4
1044 vMidID[6] = MidID(3,1); // subvolume 0
1045 vMidID[7] = MidID(2,13);// face 1,5,3
1046 break;
1047 // scv of corner 1 in subvolume 2 (bottom)
1048 case 1: vMidID[0] = MidID(0,1); // corner 1
1049 vMidID[1] = MidID(1,13);// edge 1->3
1050 vMidID[2] = MidID(2,9); // subface 1 = 1,3,2
1051 vMidID[3] = MidID(1,4); // edge 4
1052 vMidID[4] = MidID(1,0); // edge 0
1053 vMidID[5] = MidID(2,15);// face 1,3,0
1054 vMidID[6] = MidID(3,3); // subvolume 2
1055 vMidID[7] = MidID(2,0); // face 0
1056 break;
1057
1058
1059 // scv of corner 2 in subvolume 0 (top)
1060 case 2: vMidID[0] = MidID(0,2); // corner 2
1061 vMidID[1] = MidID(1,5); // edge 5
1062 vMidID[2] = MidID(2,8); // subface 0 = 1,2,3
1063 vMidID[3] = MidID(1,4); // edge 4
1064 vMidID[4] = MidID(1,9); // edge 9
1065 vMidID[5] = MidID(2,5); // face 5
1066 vMidID[6] = MidID(3,1); // subvolume 0
1067 vMidID[7] = MidID(2,4); // face 4
1068 break;
1069 // scv of corner 2 in subvolume 2 (bottom)
1070 case 3: vMidID[0] = MidID(0,2); // corner 2
1071 vMidID[1] = MidID(1,4); // edge 4
1072 vMidID[2] = MidID(2,9); // subface 1 = 1,3,2
1073 vMidID[3] = MidID(1,5); // edge 5
1074 vMidID[4] = MidID(1,1); // edge 1
1075 vMidID[5] = MidID(2,0); // face 0
1076 vMidID[6] = MidID(3,3); // subvolume 2
1077 vMidID[7] = MidID(2,1); // face 1
1078 break;
1079
1080
1081 // scv of corner 3 in subvolume 0 (top)
1082 case 4: vMidID[0] = MidID(0,3); // corner 3
1083 vMidID[1] = MidID(1,12);// edge 3->1
1084 vMidID[2] = MidID(2,8); // subface 0 = 1,2,3
1085 vMidID[3] = MidID(1,5); // edge 5
1086 vMidID[4] = MidID(1,10);// edge 10
1087 vMidID[5] = MidID(2,13);// face 1,5,3
1088 vMidID[6] = MidID(3,1); // subvolume 0
1089 vMidID[7] = MidID(2,5); // face 5
1090 break;
1091 // scv of corner 3 in subvolume 2 (bottom)
1092 case 5: vMidID[0] = MidID(0,3); // corner 3
1093 vMidID[1] = MidID(1,5); // edge 5
1094 vMidID[2] = MidID(2,9); // subface 0 = 1,3,2
1095 vMidID[3] = MidID(1,13);// edge 1->3
1096 vMidID[4] = MidID(1,2); // edge 2
1097 vMidID[5] = MidID(2,1); // face 1
1098 vMidID[6] = MidID(3,3); // subvolume 2
1099 vMidID[7] = MidID(2,15);// face 1,3,0
1100 break;
1101
1102
1103 // scv of corner 5 in subvolume 0 (top)
1104 case 6: vMidID[0] = MidID(0,5); // corner 5
1105 vMidID[1] = MidID(1,9); // edge 9
1106 vMidID[2] = MidID(2,4); // face 4
1107 vMidID[3] = MidID(1,8); // edge 8
1108 vMidID[4] = MidID(1,10);// edge 10
1109 vMidID[5] = MidID(2,5); // face 5
1110 vMidID[6] = MidID(3,1); // subvolume 0
1111 vMidID[7] = MidID(2,13);// subface 1,5,3
1112 break;
1113 // scv of corner 0 in subvolume 2 (bottom)
1114 case 7: vMidID[0] = MidID(0,0); // corner 0
1115 vMidID[1] = MidID(1,0); // edge 0
1116 vMidID[2] = MidID(2,0); // face 0
1117 vMidID[3] = MidID(1,1); // edge 1
1118 vMidID[4] = MidID(1,2); // edge 2
1119 vMidID[5] = MidID(2,14);// subface 1,0,3
1120 vMidID[6] = MidID(3,3); // subvolume 2
1121 vMidID[7] = MidID(2,1); // face 1
1122 break;
1123
1124
1125 // scv of corner 1 in subvolume 1 (top)
1126 case 8: vMidID[0] = MidID(0,1); // corner 1
1127 vMidID[1] = MidID(1,13);// edge 1->3
1128 vMidID[2] = MidID(2,10);// subface 2 = 1,3,4
1129 vMidID[3] = MidID(1,7); // edge 7
1130 vMidID[4] = MidID(1,8); // edge 8
1131 vMidID[5] = MidID(2,12);// face 1,3,5
1132 vMidID[6] = MidID(3,2); // subvolume 1
1133 vMidID[7] = MidID(2,7); // face 7
1134 break;
1135 // scv of corner 1 in subvolume 3 (bottom)
1136 case 9: vMidID[0] = MidID(0,1); // corner 1
1137 vMidID[1] = MidID(1,7); // edge 7
1138 vMidID[2] = MidID(2,11);// subface 3 = 1,4,3
1139 vMidID[3] = MidID(1,12);// edge 3->1
1140 vMidID[4] = MidID(1,0); // edge 0
1141 vMidID[5] = MidID(2,3); // face 3
1142 vMidID[6] = MidID(3,4); // subvolume 3
1143 vMidID[7] = MidID(2,14);// face 1,0,3
1144 break;
1145
1146
1147 // scv of corner 3 in subvolume 1 (top)
1148 case 10:vMidID[0] = MidID(0,3); // corner 3
1149 vMidID[1] = MidID(1,6); // edge 6
1150 vMidID[2] = MidID(2,10);// subface 2 = 1,3,4
1151 vMidID[3] = MidID(1,13);// edge 1->3
1152 vMidID[4] = MidID(1,10);// edge 10
1153 vMidID[5] = MidID(2,6); // face 6
1154 vMidID[6] = MidID(3,2); // subvolume 1
1155 vMidID[7] = MidID(2,12);// face 1,3,5
1156 break;
1157 // scv of corner 3 in subvolume 3 (bottom)
1158 case 11:vMidID[0] = MidID(0,3); // corner 3
1159 vMidID[1] = MidID(1,12);// edge 3->1
1160 vMidID[2] = MidID(2,11);// subface 3 = 1,4,3
1161 vMidID[3] = MidID(1,6); // edge 6
1162 vMidID[4] = MidID(1,2); // edge 2
1163 vMidID[5] = MidID(2,14);// face 1,0,3
1164 vMidID[6] = MidID(3,4); // subvolume 3
1165 vMidID[7] = MidID(2,2); // face 2
1166 break;
1167
1168
1169 // scv of corner 4 in subvolume 1 (top)
1170 case 12:vMidID[0] = MidID(0,4); // corner 4
1171 vMidID[1] = MidID(1,7); // edge 7
1172 vMidID[2] = MidID(2,10);// subface 2 = 1,3,4
1173 vMidID[3] = MidID(1,6); // edge 6
1174 vMidID[4] = MidID(1,11);// edge 11
1175 vMidID[5] = MidID(2,7); // face 7
1176 vMidID[6] = MidID(3,2); // subvolume 1
1177 vMidID[7] = MidID(2,6); // face 6
1178 break;
1179 // scv of corner 4 in subvolume 3 (bottom)
1180 case 13:vMidID[0] = MidID(0,4); // corner 4
1181 vMidID[1] = MidID(1,6); // edge 6
1182 vMidID[2] = MidID(2,11);// subface 3 = 1,4,3
1183 vMidID[3] = MidID(1,7); // edge 7
1184 vMidID[4] = MidID(1,3); // edge 3
1185 vMidID[5] = MidID(2,2); // face 2
1186 vMidID[6] = MidID(3,4); // subvolume 3
1187 vMidID[7] = MidID(2,3); // face 3
1188 break;
1189
1190
1191 // scv of corner 5 in subvolume 1 (top)
1192 case 14:vMidID[0] = MidID(0,5); // corner 5
1193 vMidID[1] = MidID(1,10);// edge 10
1194 vMidID[2] = MidID(2,12);// subface 1,3,5
1195 vMidID[3] = MidID(1,8); // edge 8
1196 vMidID[4] = MidID(1,11);// edge 11
1197 vMidID[5] = MidID(2,6); // face 6
1198 vMidID[6] = MidID(3,2); // subvolume 1
1199 vMidID[7] = MidID(2,7); // face 7
1200 break;
1201 // scv of corner 0 in subvolume 3 (bottom)
1202 case 15:vMidID[0] = MidID(0,0); // corner 0
1203 vMidID[1] = MidID(1,0); // edge 0
1204 vMidID[2] = MidID(2,15);// subface 1,3,0
1205 vMidID[3] = MidID(1,2); // edge 2
1206 vMidID[4] = MidID(1,3); // edge 3
1207 vMidID[5] = MidID(2,3); // face 3
1208 vMidID[6] = MidID(3,4); // subvolume 3
1209 vMidID[7] = MidID(2,2); // face 2
1210 break;
1211
1212
1213 default:UG_THROW("Octahedron only has 16 SCVs (no. 0-15), but requested no. " << i << ".");
1214 break;
1215 }
1216 }
1217};
1220
1222// Dimension dependent traits DIM FV1
1224
1226template <int TDim, int TWorldDim> struct fv1_dim_traits_base
1227{
1229 static const int dim = TDim;
1230
1233
1236 (
1237 const ref_elem_type& refElem,
1238 ReferenceObjectID roid,
1239 size_t& numSCV,
1240 size_t& numSCVF
1241 )
1242 {
1243 if(roid != ROID_PYRAMID && roid != ROID_OCTAHEDRON)
1244 {
1245 numSCV = refElem.num(0);
1246 numSCVF = refElem.num(1);
1247 }
1248 else if(dim == 3 && roid == ROID_PYRAMID)
1249 {
1250 UG_WARNING("Pyramid Finite Volume Geometry for 1st order currently "
1251 "implemented in DimFV1Geom EXPERIMENTATLLY. Please contact "
1252 "Martin Stepniewski or Andreas Vogel if you see this message.")
1253
1254 numSCV = 4*refElem.num(1);
1255 numSCVF = 2*refElem.num(1);
1256 }
1257 else if(dim == 3 && roid == ROID_OCTAHEDRON)
1258 {
1259 // Case octahedron
1260 numSCV = 16;
1261 numSCVF = 24;
1262 }
1263 else
1264 UG_THROW ("fv1_dim_traits_base: Unsupported combination of dimension and reference element.");
1265 }
1266
1269 (
1270 const ref_elem_type& refElem,
1271 ReferenceObjectID roid,
1272 size_t i,
1273 size_t& From,
1274 size_t& To
1275 )
1276 {
1277 if (roid != ROID_PYRAMID && roid != ROID_OCTAHEDRON)
1278 {
1279 From = refElem.id(1, i, 0, 0);
1280 To = refElem.id(1, i, 0, 1);
1281 }
1282 // special case pyramid (scvf not mappable by edges)
1283 else if (dim == 3 && roid == ROID_PYRAMID)
1284 {
1285 // map according to order defined in ComputeSCVFMidID
1286 From = fv1_traits_ReferencePyramid::scvf_from_to ((const ReferencePyramid&) refElem, i, 0);
1287 To = fv1_traits_ReferencePyramid::scvf_from_to ((const ReferencePyramid&) refElem, i, 1);
1288 }
1289 // special case octahedron (scvf not mappable by edges)
1290 else if(dim == 3 && roid == ROID_OCTAHEDRON)
1291 {
1292 // map according to order defined in ComputeSCVFMidID
1295 }
1296 else
1297 UG_THROW ("fv1_dim_traits_base: Unsupported combination of dimension and reference element.");
1298 }
1299
1301 static size_t dim_scv_node_id
1302 (
1303 const ref_elem_type& refElem,
1304 ReferenceObjectID roid,
1305 size_t i
1306 )
1307 {
1308 // "classical" elements
1309 if (roid != ROID_PYRAMID && roid != ROID_OCTAHEDRON)
1310 return i;
1311
1312 // special case pyramid (scv not mappable by corners)
1313 if(dim == 3 && roid == ROID_PYRAMID)
1315
1316 // special case octahedron (scvf not mappable by edges)
1317 if(dim == 3 && roid == ROID_OCTAHEDRON)
1319
1320 UG_THROW ("fv1_dim_traits_base: Unsupported combination of dimension and reference element.");
1321 }
1322};
1323
1325template <int TDim, int TWorldDim> struct fv1_dim_traits;
1326
1327template <> struct fv1_dim_traits<1, 1> : public fv1_traits<ReferenceEdge, 1>, public fv1_dim_traits_base<1, 1> {};
1328template <> struct fv1_dim_traits<1, 2> : public fv1_traits<ReferenceEdge, 2>, public fv1_dim_traits_base<1, 2> {};
1329template <> struct fv1_dim_traits<1, 3> : public fv1_traits<ReferenceEdge, 3>, public fv1_dim_traits_base<1, 3> {};
1330
1331template <> struct fv1_dim_traits<2, 2> : public fv1_traits_ReferenceFace2d, public fv1_dim_traits_base<2, 2> {};
1332template <> struct fv1_dim_traits<2, 3> : public fv1_traits_ReferenceFace3d, public fv1_dim_traits_base<2, 3>
1333{
1334 static void NormalOnSCVF(MathVector<3>& outNormal,
1335 const MathVector<3>* vSCVFCorner,
1336 const MathVector<3>* vElemCorner)
1337 {
1338 // Little bit dirty, but should be correct:
1339 // Even if the true element has more than three vertices (quadrilateral),
1340 // we only need three to compute the direction of the normal ElemNormal in NormalOnSCVF_Face,
1341 // the norm is not needed!
1342 fv1_traits_ReferenceFace3d::NormalOnSCVF_Face<ReferenceTriangle>(outNormal, vSCVFCorner, vElemCorner);
1343 //UG_THROW("Not implemented.")
1344 }
1345
1346};
1347
1348template <> struct fv1_dim_traits<3, 3> : public fv1_traits_ReferenceVolume, public fv1_dim_traits_base<3, 3> {};
1349
1351// Hanging Finite Volume Traits
1353
1355template <typename TRefElem, int TWorldDim> struct hfv1_traits
1356{
1357 const static size_t NumCornersOfSCVF;
1358 const static size_t MaxNumCornersOfSCV;
1359
1360 static void NormalOnSCVF(MathVector<TWorldDim>& outNormal, const MathVector<TWorldDim>* vCornerCoords);
1361
1362 typedef void scv_type;
1363};
1364
1366// 1D Reference Element
1368
1370{
1371 const static size_t NumCornersOfSCVF = 1;
1372 const static size_t MaxNumCornersOfSCV = 2;
1374};
1375
1377{
1378 static void NormalOnSCVF(MathVector<1>& outNormal, const MathVector<1>* vCornerCoords)
1379 {ElementNormal<ReferenceVertex, 1>(outNormal, vCornerCoords);}
1380};
1381
1383{
1384 static void NormalOnSCVF(MathVector<2>& outNormal, const MathVector<2>* vCornerCoords)
1385 {UG_THROW("Not implemented");}
1386};
1387
1389{
1390 static void NormalOnSCVF(MathVector<3>& outNormal, const MathVector<3>* vCornerCoords)
1391 {UG_THROW("Not implemented");}
1392};
1393
1395// 2D Reference Element
1397
1399{
1400 const static size_t NumCornersOfSCVF = 2;
1401 const static size_t MaxNumCornersOfSCV = 4;
1403};
1404
1406{
1407 static void NormalOnSCVF(MathVector<2>& outNormal, const MathVector<2>* vCornerCoords)
1408 {ElementNormal<ReferenceEdge, 2>(outNormal, vCornerCoords);}
1409};
1410
1412{
1413 static void NormalOnSCVF(MathVector<3>& outNormal, const MathVector<3>* vCornerCoords)
1414 {UG_THROW("Not implemented");}
1415};
1416
1418{
1419 static void NormalOnSCVF(MathVector<2>& outNormal, const MathVector<2>* vCornerCoords)
1420 {ElementNormal<ReferenceEdge, 2>(outNormal, vCornerCoords);}
1421};
1422
1424{
1425 static void NormalOnSCVF(MathVector<3>& outNormal, const MathVector<3>* vCornerCoords)
1426 {UG_THROW("Not implemented");}
1427};
1428
1430// 3D Reference Element
1432
1434{
1435 static void NormalOnSCVF(MathVector<3>& outNormal, const MathVector<3>* vCornerCoords)
1436 {ElementNormal<ReferenceTriangle, 3>(outNormal, vCornerCoords);}
1437
1439};
1440
1442{
1443 const static size_t NumCornersOfSCVF = 3;
1444 const static size_t MaxNumCornersOfSCV = 8;
1445};
1446
1448{
1449 const static size_t NumCornersOfSCVF = 3;
1450 const static size_t MaxNumCornersOfSCV = 8;
1451};
1452
1454{
1455 const static size_t NumCornersOfSCVF = 3;
1456 const static size_t MaxNumCornersOfSCV = 10;
1457};
1458
1460{
1461 const static size_t NumCornersOfSCVF = 3;
1462 const static size_t MaxNumCornersOfSCV = 8;
1463};
1464
1466{
1467 const static size_t NumCornersOfSCVF = 3;
1468 const static size_t MaxNumCornersOfSCV = 8;
1469};
1470
1471template <int TDim> struct hdimfv1_traits
1472{
1473 typedef void scv_type;
1474 typedef void elem_type_0;
1475 typedef void elem_type_1;
1476 typedef void elem_type_2;
1477 typedef void elem_type_3;
1478 typedef void elem_type_4;
1479 const static size_t NumCornersOfSCVF;
1480 const static size_t MaxNumCornersOfSCV;
1481};
1482
1494
1506
1518
1519
1521// Functions
1523
1524template <typename TRefElem, int TWorldDim>
1526{
1527 hfv1_traits<TRefElem, TWorldDim>::NormalOnSCVF(outNormal, vCornerCoords);
1528}
1529
1531// FVHO: Finite Volume for Higher Order traits
1533
1535template <int TOrder, typename TRefElem, int TWorldDim> struct fvho_traits
1536{
1537// can be inherited from fv1_traits (since the same)
1538 const static size_t NumCornersOfSCVF;
1539 const static size_t MaxNumCornersOfSCV;
1540 static void NormalOnSCVF(MathVector<TWorldDim>& outNormal, const MathVector<TWorldDim>* vCornerCoords);
1541 typedef void scv_type;
1542
1543// own data
1544 const static size_t NumSubElem;
1545};
1546
1547} // end namespace ug
1548
1549#endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_VOLUME_UTIL__ */
parameterString p
dimension dependent base class for reference elements
Definition reference_element.h:183
a mathematical Vector with N entries.
Definition math_vector.h:97
Definition reference_element.h:345
size_t num(int dim) const
returns the number of geometric objects of dim
Definition reference_element.h:95
int id(int dim_i, size_t i, int dim_j, size_t j) const
id of object j in dimension dim_j of obj i in dimension dim_i
Definition reference_element.h:127
reference element for a hexahedron
Definition reference_element.h:648
Definition reference_element.h:699
Definition reference_element.h:595
Definition reference_element.h:546
static const int numEdges
number of eges
Definition reference_element.h:558
Definition reference_element.h:445
Definition reference_element.h:494
Definition reference_element.h:394
Definition reference_element.h:303
#define UG_THROW(msg)
Definition error.h:57
#define UG_WARNING(msg)
Definition log.h:328
double number
Definition types.h:124
void VecNormalize(vector_t &vOut, const vector_t &v)
scales a vector_t to unit length
Definition math_vector_functions_common_impl.hpp:501
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition math_vector_functions_common_impl.hpp:226
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
returns the distance of two vector_ts.
Definition math_vector_functions_common_impl.hpp:375
void VecAdd(vector_t &vOut, const vector_t &v1, const vector_t &v2)
adds two MathVector<N>s and stores the result in a third one
Definition math_vector_functions_common_impl.hpp:185
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
scales a MathVector<N>
Definition math_vector_functions_common_impl.hpp:252
the ug namespace
ReferenceObjectID
these ids are used to identify the shape of a geometric object.
Definition grid_base_objects.h:74
@ ROID_PYRAMID
Definition grid_base_objects.h:83
@ ROID_OCTAHEDRON
Definition grid_base_objects.h:84
void HangingNormalOnSCVF(MathVector< TWorldDim > &outNormal, const MathVector< TWorldDim > *vCornerCoords)
Definition fv_util.h:1525
void ElementNormal< ReferenceQuadrilateral, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Quadrilateral in 3d.
Definition geometry_util.h:579
void ElementNormal< ReferenceTriangle, 3 >(MathVector< 3 > &normalOut, const MathVector< 3 > *vCornerCoords)
Normal to a Triangle in 3d.
Definition geometry_util.h:556
void ElementNormal< ReferenceEdge, 2 >(MathVector< 2 > &normalOut, const MathVector< 2 > *vCornerCoords)
Normal to a Line in 2d.
Definition geometry_util.h:500
@ VOLUME
Definition grid_base_objects.h:63
@ VERTEX
Definition grid_base_objects.h:60
@ EDGE
Definition grid_base_objects.h:61
@ FACE
Definition grid_base_objects.h:62
void ElementNormal< ReferenceVertex, 1 >(MathVector< 1 > &normalOut, const MathVector< 1 > *vCornerCoords)
Normal to a Point in 1d.
Definition geometry_util.h:436
void AveragePositions(TPosition &vOut, const TPosition *vCornerCoords, size_t num)
averages positions by arithmetic mean
Definition fv_util.h:59
helper class to store dimension and id of a midpoint of a sub-element
Definition fv_geom_base.h:41
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:1334
Base for the Traits for Finite Volumes for a generic element of the fixed dimensionalities.
Definition fv_util.h:1227
static void get_dim_scvf_from_to(const ref_elem_type &refElem, ReferenceObjectID roid, size_t i, size_t &From, size_t &To)
returns the 'from' and 'to' corner indices for a scvf
Definition fv_util.h:1269
static size_t dim_scv_node_id(const ref_elem_type &refElem, ReferenceObjectID roid, size_t i)
returns the node id for a scv
Definition fv_util.h:1302
static const int dim
dimension of reference element
Definition fv_util.h:1229
static void dim_get_num_SCV_and_SCVF(const ref_elem_type &refElem, ReferenceObjectID roid, size_t &numSCV, size_t &numSCVF)
returns the number of the SCV
Definition fv_util.h:1236
DimReferenceElement< dim > ref_elem_type
generic reference element type
Definition fv_util.h:1232
Traits for Finite Volumes for a generic element of the fixed dimensionalities.
Definition fv_util.h:1325
static void NormalOnBF(MathVector< 1 > &outNormal, const MathVector< 1 > *vSCVFCorner, const MathVector< 1 > *vElemCorner)
Definition fv_util.h:239
static void NormalOnSCVF(MathVector< 1 > &outNormal, const MathVector< 1 > *vSCVFCorner, const MathVector< 1 > *vElemCorner)
Definition fv_util.h:232
static void NormalOnSCVF(MathVector< 2 > &outNormal, const MathVector< 2 > *vSCVFCorner, const MathVector< 2 > *vElemCorner)
Definition fv_util.h:251
static void NormalOnBF(MathVector< 2 > &outNormal, const MathVector< 2 > *vSCVFCorner, const MathVector< 2 > *vElemCorner)
Definition fv_util.h:258
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:277
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:270
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:561
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:557
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:392
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:396
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:372
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:376
Definition fv_util.h:214
ReferenceVertex scvf_type
Definition fv_util.h:224
static const size_t maxNumSCV
Definition fv_util.h:216
static const size_t NumCornersOfBF
Definition fv_util.h:221
static const size_t maxNumSCVF
Definition fv_util.h:215
ReferenceEdge scv_type
Definition fv_util.h:223
static const size_t NumCornersOfSCVF
Definition fv_util.h:219
static const size_t maxNSH
Definition fv_util.h:217
ReferenceVertex bf_type
Definition fv_util.h:225
static const size_t NumCornersOfSCV
Definition fv_util.h:220
Definition fv_util.h:305
static void NormalOnBF(MathVector< 2 > &outNormal, const MathVector< 2 > *vSCVFCorner, const MathVector< 2 > *vElemCorner)
Definition fv_util.h:310
static void NormalOnSCVF(MathVector< 2 > &outNormal, const MathVector< 2 > *vSCVFCorner, const MathVector< 2 > *vElemCorner)
Definition fv_util.h:306
Definition fv_util.h:319
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:356
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:350
static void NormalOnSCVF_Face(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:321
Definition fv_util.h:290
static const size_t maxNumSCVF
Definition fv_util.h:291
static const size_t NumCornersOfBF
Definition fv_util.h:297
static const size_t NumCornersOfSCV
Definition fv_util.h:296
ReferenceQuadrilateral scv_type
Definition fv_util.h:299
static const size_t maxNSH
Definition fv_util.h:293
static const size_t maxNumSCV
Definition fv_util.h:292
ReferenceEdge scvf_type
Definition fv_util.h:300
static const size_t NumCornersOfSCVF
Definition fv_util.h:295
ReferenceEdge bf_type
Definition fv_util.h:301
Octahedra: dimension-independent part of the FV1 traits.
Definition fv_util.h:573
@ MAXSUBSTRUCTCORNERS
Definition fv_util.h:594
static const size_t numSCVF
overridden field from fv1_traits_most_common
Definition fv_util.h:584
static size_t substruct_num(int dim_i, size_t i, int dim_j)
returns the number of objects of dim for a sub-geometric object of the implicit interior substructure
Definition fv_util.h:719
static size_t scv_node_id(const ReferenceOctahedron &refElem, size_t i)
returns the node id for a scv (overridden function from fv1_traits_most_common)
Definition fv_util.h:810
static size_t scvf_from_to(const ReferenceOctahedron &refElem, size_t i, size_t ft)
returns the 'from' and 'to' corner indices for a scvf (overridden function from fv1_traits_most_commo...
Definition fv_util.h:761
static int substruct_coID(int dim_i, size_t i, size_t j)
returns the id of corner j of obj i in dimension dim_i of the implicit interior substructure
Definition fv_util.h:611
@ MAXDIM
Definition fv_util.h:588
@ MAXSUBSTRUCTOBJECTS
Definition fv_util.h:591
static size_t substruct_num(int dim)
returns the number of implicit interior substructure geometric objects of dim
Definition fv_util.h:691
static void scvf_mid_id(const ReferenceOctahedron &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scvf i.
Definition fv_util.h:846
static void scv_mid_id(const ReferenceOctahedron &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scv i.
Definition fv_util.h:1029
static const size_t numSCV
overridden field from fv1_traits_most_common
Definition fv_util.h:582
Pyramids: dimension-independent part of the FV1 traits.
Definition fv_util.h:455
static void scvf_mid_id(const ReferencePyramid &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scvf i.
Definition fv_util.h:495
ReferenceTetrahedron scv_type
Definition fv_util.h:464
ReferenceQuadrilateral bf_type
Definition fv_util.h:466
static const size_t NumCornersOfSCV
Definition fv_util.h:461
static size_t scvf_from_to(const ReferencePyramid &refElem, size_t i, size_t ft)
returns the 'from' and 'to' corner indices for a scvf (overridden function from fv1_traits_most_commo...
Definition fv_util.h:470
static const size_t NumCornersOfSCVF
Definition fv_util.h:460
ReferenceTriangle scvf_type
Definition fv_util.h:465
static const size_t numSCVF
overridden field from fv1_traits_most_common
Definition fv_util.h:458
static const size_t NumCornersOfBF
Definition fv_util.h:462
static size_t scv_node_id(const ReferencePyramid &refElem, size_t i)
returns the node id for a scv (overridden function from fv1_traits_most_common)
Definition fv_util.h:481
static const size_t numSCV
overridden field from fv1_traits_most_common
Definition fv_util.h:456
static void scv_mid_id(const ReferencePyramid &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scv i.
Definition fv_util.h:520
Definition fv_util.h:409
static const size_t maxNumSCV
Definition fv_util.h:411
static const size_t NumCornersOfBF
Definition fv_util.h:416
static const size_t NumCornersOfSCVF
Definition fv_util.h:414
ReferenceQuadrilateral bf_type
Definition fv_util.h:420
static const size_t maxNumSCVF
Definition fv_util.h:410
static void NormalOnBF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:426
static const size_t maxNSH
Definition fv_util.h:412
ReferenceHexahedron scv_type
Definition fv_util.h:418
static const size_t NumCornersOfSCV
Definition fv_util.h:415
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vSCVFCorner, const MathVector< 3 > *vElemCorner)
Definition fv_util.h:422
ReferenceQuadrilateral scvf_type
Definition fv_util.h:419
Base class, some fields are redefined in the instantiations for particular elements.
Definition fv_util.h:77
static const size_t numSCVF
number of SubControlVolumeFaces (for most of the elements - overridden for e.g. ROID_PYRAMID and ROID...
Definition fv_util.h:85
static size_t scv_node_id(const ref_elem_type &refElem, size_t i)
returns the node id for a scv
Definition fv_util.h:100
static size_t scvf_from_to(const ref_elem_type &refElem, size_t i, size_t ft)
returns the 'from' and 'to' corner indices for a scvf
Definition fv_util.h:89
static const size_t numSCV
number of SubControlVolumes (for most of the elements - overridden for e.g. ROID_PYRAMID and ROID_OCT...
Definition fv_util.h:82
TRefElem ref_elem_type
type of reference element
Definition fv_util.h:79
static void scv_mid_id(const ref_elem_type &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scv i.
Definition fv_util.h:138
static void scvf_mid_id(const ref_elem_type &refElem, MidID *vMidID, size_t i)
Calculates array vMidID for scvf i.
Definition fv_util.h:110
Traits for Finite Volumes (dummy implementation, s. the instantiations below)
Definition fv_util.h:178
static const size_t NumCornersOfSCV
Definition fv_util.h:188
static const size_t maxNSH
Definition fv_util.h:182
void scv_type
Definition fv_util.h:204
static void NormalOnBF(MathVector< TWorldDim > &outNormal, const MathVector< TWorldDim > *vSCVFCorner, const MathVector< TWorldDim > *vElemCorner)
static void NormalOnSCVF(MathVector< TWorldDim > &outNormal, const MathVector< TWorldDim > *vSCVFCorner, const MathVector< TWorldDim > *vElemCorner)
static const size_t NumCornersOfSCVF
Definition fv_util.h:185
void bf_type
Definition fv_util.h:206
static const size_t NumCornersOfBF
Definition fv_util.h:191
static const size_t maxNumSCV
Definition fv_util.h:181
void scvf_type
Definition fv_util.h:205
static const size_t maxNumSCVF
Definition fv_util.h:180
Traits for Finite Volumes of higher order.
Definition fv_util.h:1536
static const size_t MaxNumCornersOfSCV
Definition fv_util.h:1539
static void NormalOnSCVF(MathVector< TWorldDim > &outNormal, const MathVector< TWorldDim > *vCornerCoords)
void scv_type
Definition fv_util.h:1541
static const size_t NumCornersOfSCVF
Definition fv_util.h:1538
static const size_t NumSubElem
Definition fv_util.h:1544
ReferenceEdge elem_type_3
Definition fv_util.h:1489
ReferenceEdge elem_type_1
Definition fv_util.h:1487
ReferenceEdge elem_type_4
Definition fv_util.h:1490
ReferenceEdge scv_type
Definition fv_util.h:1485
ReferenceEdge elem_type_0
Definition fv_util.h:1486
ReferenceEdge elem_type_2
Definition fv_util.h:1488
ReferenceQuadrilateral elem_type_1
Definition fv_util.h:1499
ReferenceTriangle elem_type_0
Definition fv_util.h:1498
ReferenceQuadrilateral elem_type_4
Definition fv_util.h:1502
ReferenceTriangle elem_type_2
Definition fv_util.h:1500
ReferenceQuadrilateral elem_type_3
Definition fv_util.h:1501
ReferenceQuadrilateral scv_type
Definition fv_util.h:1497
ReferenceTetrahedron elem_type_0
Definition fv_util.h:1510
ReferencePyramid elem_type_1
Definition fv_util.h:1511
ReferenceTetrahedron scv_type
Definition fv_util.h:1509
ReferenceHexahedron elem_type_3
Definition fv_util.h:1513
ReferencePrism elem_type_2
Definition fv_util.h:1512
ReferenceOctahedron elem_type_4
Definition fv_util.h:1514
Definition fv_util.h:1472
void elem_type_3
Definition fv_util.h:1477
void elem_type_2
Definition fv_util.h:1476
void elem_type_0
Definition fv_util.h:1474
void elem_type_4
Definition fv_util.h:1478
void scv_type
Definition fv_util.h:1473
static const size_t MaxNumCornersOfSCV
Definition fv_util.h:1480
static const size_t NumCornersOfSCVF
Definition fv_util.h:1479
void elem_type_1
Definition fv_util.h:1475
static void NormalOnSCVF(MathVector< 1 > &outNormal, const MathVector< 1 > *vCornerCoords)
Definition fv_util.h:1378
static void NormalOnSCVF(MathVector< 2 > &outNormal, const MathVector< 2 > *vCornerCoords)
Definition fv_util.h:1384
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vCornerCoords)
Definition fv_util.h:1390
static void NormalOnSCVF(MathVector< 2 > &outNormal, const MathVector< 2 > *vCornerCoords)
Definition fv_util.h:1419
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vCornerCoords)
Definition fv_util.h:1425
static void NormalOnSCVF(MathVector< 2 > &outNormal, const MathVector< 2 > *vCornerCoords)
Definition fv_util.h:1407
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vCornerCoords)
Definition fv_util.h:1413
Definition fv_util.h:1370
static const size_t MaxNumCornersOfSCV
Definition fv_util.h:1372
ReferenceEdge scv_type
Definition fv_util.h:1373
static const size_t NumCornersOfSCVF
Definition fv_util.h:1371
Definition fv_util.h:1399
ReferenceQuadrilateral scv_type
Definition fv_util.h:1402
static const size_t NumCornersOfSCVF
Definition fv_util.h:1400
static const size_t MaxNumCornersOfSCV
Definition fv_util.h:1401
Definition fv_util.h:1434
static void NormalOnSCVF(MathVector< 3 > &outNormal, const MathVector< 3 > *vCornerCoords)
Definition fv_util.h:1435
ReferenceTetrahedron scv_type
Definition fv_util.h:1438
Traits for hanging finite volume (dummy implementation)
Definition fv_util.h:1356
static const size_t NumCornersOfSCVF
Definition fv_util.h:1357
static const size_t MaxNumCornersOfSCV
Definition fv_util.h:1358
static void NormalOnSCVF(MathVector< TWorldDim > &outNormal, const MathVector< TWorldDim > *vCornerCoords)
void scv_type
Definition fv_util.h:1362