ug4
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 
47 namespace ug{
48 
50 
58 template <typename TPosition>
59 void 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 
76 template <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 
176 template <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 
228 template <> struct fv1_traits<ReferenceEdge, 1>
229 : public fv1_traits_ReferenceEdge,
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 
247 template <> struct fv1_traits<ReferenceEdge, 2>
248 : public fv1_traits_ReferenceEdge,
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 
266 template <> struct fv1_traits<ReferenceEdge, 3>
267 : public fv1_traits_ReferenceEdge,
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 
364 template <> struct fv1_traits<ReferenceTriangle, 2>
366  public fv1_traits_most_common<ReferenceTriangle>
367 {};
368 template <> struct fv1_traits<ReferenceTriangle, 3>
369 : public fv1_traits_ReferenceFace,
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 
384 template <> struct fv1_traits<ReferenceQuadrilateral, 2>
386  public fv1_traits_most_common<ReferenceQuadrilateral>
387 {};
388 template <> struct fv1_traits<ReferenceQuadrilateral, 3>
389 : public fv1_traits_ReferenceFace,
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 
434 template <> struct fv1_traits<ReferenceTetrahedron, 3>
436  public fv1_traits_most_common<ReferenceTetrahedron>
437 {};
438 template <> struct fv1_traits<ReferencePrism, 3>
440  public fv1_traits_most_common<ReferencePrism>
441 {};
442 template <> 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 
1226 template <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
1293  From = fv1_traits_ReferenceOctahedron::scvf_from_to ((const ReferenceOctahedron&) refElem, i, 0);
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)
1314  return fv1_traits_ReferencePyramid::scv_node_id ((const ReferencePyramid&) refElem, i);
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 
1325 template <int TDim, int TWorldDim> struct fv1_dim_traits;
1326 
1327 template <> struct fv1_dim_traits<1, 1> : public fv1_traits<ReferenceEdge, 1>, public fv1_dim_traits_base<1, 1> {};
1328 template <> struct fv1_dim_traits<1, 2> : public fv1_traits<ReferenceEdge, 2>, public fv1_dim_traits_base<1, 2> {};
1329 template <> struct fv1_dim_traits<1, 3> : public fv1_traits<ReferenceEdge, 3>, public fv1_dim_traits_base<1, 3> {};
1330 
1331 template <> struct fv1_dim_traits<2, 2> : public fv1_traits_ReferenceFace2d, public fv1_dim_traits_base<2, 2> {};
1332 template <> 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 
1348 template <> struct fv1_dim_traits<3, 3> : public fv1_traits_ReferenceVolume, public fv1_dim_traits_base<3, 3> {};
1349 
1351 // Hanging Finite Volume Traits
1353 
1355 template <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 
1376 template <> struct hfv1_traits<ReferenceEdge, 1> : public hfv1_traits_ReferenceEdge
1377 {
1378  static void NormalOnSCVF(MathVector<1>& outNormal, const MathVector<1>* vCornerCoords)
1379  {ElementNormal<ReferenceVertex, 1>(outNormal, vCornerCoords);}
1380 };
1381 
1382 template <> struct hfv1_traits<ReferenceEdge, 2> : public hfv1_traits_ReferenceEdge
1383 {
1384  static void NormalOnSCVF(MathVector<2>& outNormal, const MathVector<2>* vCornerCoords)
1385  {UG_THROW("Not implemented");}
1386 };
1387 
1388 template <> struct hfv1_traits<ReferenceEdge, 3> : public hfv1_traits_ReferenceEdge
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 
1471 template <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 
1483 template <> struct hdimfv1_traits<1>
1484 {
1491  const static size_t NumCornersOfSCVF = 1;
1492  const static size_t MaxNumCornersOfSCV = 2;
1493 };
1494 
1495 template <> struct hdimfv1_traits<2>
1496 {
1503  const static size_t NumCornersOfSCVF = 2;
1504  const static size_t MaxNumCornersOfSCV = 4;
1505 };
1506 
1507 template <> struct hdimfv1_traits<3>
1508 {
1515  const static size_t NumCornersOfSCVF = 3;
1516  const static size_t MaxNumCornersOfSCV = 10;
1517 };
1518 
1519 
1521 // Functions
1523 
1524 template <typename TRefElem, int TWorldDim>
1526 {
1527  hfv1_traits<TRefElem, TWorldDim>::NormalOnSCVF(outNormal, vCornerCoords);
1528 }
1529 
1531 // FVHO: Finite Volume for Higher Order traits
1533 
1535 template <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
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
static const int dim
#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