LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/disc_util - fv1_geom.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 274 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 2607 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       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__FV1_GEOMETRY__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FV1_GEOMETRY__
      35              : 
      36              : // extern libraries
      37              : #include <cmath>
      38              : #include <map>
      39              : #include <vector>
      40              : 
      41              : // other ug4 modules
      42              : #include "common/common.h"
      43              : 
      44              : // library intern includes
      45              : #include "lib_grid/tools/subset_handler_interface.h"
      46              : #include "lib_disc/reference_element/reference_element.h"
      47              : #include "lib_disc/reference_element/reference_element_traits.h"
      48              : #include "lib_disc/reference_element/reference_mapping.h"
      49              : #include "lib_disc/reference_element/reference_mapping_provider.h"
      50              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      51              : #include "lib_disc/local_finite_element/lagrange/lagrangep1.h"
      52              : #include "lib_disc/quadrature/gauss/gauss_quad.h"
      53              : #include "fv_util.h"
      54              : #include "fv_geom_base.h"
      55              : 
      56              : namespace ug{
      57              : 
      58              : ////////////////////////////////////////////////////////////////////////////////
      59              : // FV1 Geometry for Reference Element Type
      60              : ////////////////////////////////////////////////////////////////////////////////
      61              : 
      62              : // forward declaration
      63              : template <   typename TElem, int TWorldDim, bool TCondensed> class FV1Geometry_gen;
      64              : 
      65              : /// Geometry and shape functions for 1st order Vertex-Centered Finite Volume
      66              : /**
      67              :  * The class provides the geometry and shape functions for 1st order Vertex-Centered
      68              :  * Finite Element Finite Volume method based on the Donald Diagrams.
      69              :  *
      70              :  * Cf. class FV1Geometry_gen for the implementation.
      71              :  * 
      72              :  * \tparam      TElem           Element type
      73              :  * \tparam      TWorldDim       (physical) world dimension
      74              :  */
      75              : template <typename TElem, int TWorldDim>
      76            0 : class FV1Geometry : public FV1Geometry_gen<TElem, TWorldDim, false> {};
      77              : 
      78              : /// Geometry and shape functions for 1st order Vertex-Centered Finite Volume
      79              : /**
      80              :  * The class provides the geometry and shape functions for 1st order Vertex-Centered
      81              :  * Finite Element Finite Volume method based on the Donald Diagrams.
      82              :  * 
      83              :  * This class shifts the subcontrol volume face integration
      84              :  * points to the edges. This allows to reduce the matrix pattern and to avoid positive
      85              :  * off-diagonal entries in some cases. (For ex., the discretization of the Laplacian on
      86              :  * a grid of rectangles retains results in the 5-point stencil.) However note that, in many
      87              :  * cases, this leads to the discretization order reduction.
      88              :  *
      89              :  * Cf. class FV1Geometry_gen for the implementation.
      90              :  * 
      91              :  * \tparam      TElem           Element type
      92              :  * \tparam      TWorldDim       (physical) world dimension
      93              :  */
      94              : template <typename TElem, int TWorldDim>
      95            0 : class FV1CondensedGeometry : public FV1Geometry_gen<TElem, TWorldDim, true> {};
      96              : 
      97              : /// Geometry and shape functions for 1st order Vertex-Centered Finite Volume
      98              : /**
      99              :  * The class provides the geometry and shape functions for 1st order Vertex-Centered
     100              :  * Finite Element Finite Volume method based on the Donald Diagrams.
     101              :  * 
     102              :  * The class provides an option (TCondensed) to shift the subcontrol volume face integration
     103              :  * points to the edges. This allows to reduce the matrix pattern and to avoid positive
     104              :  * off-diagonal entries in some cases. (For ex., the discretization of the Laplacian on
     105              :  * a grid of rectangles retains results in the 5-point stencil.) However note that, in many
     106              :  * cases, this leads to the discretization order reduction.
     107              :  * 
     108              :  * \tparam      TElem           Element type
     109              :  * \tparam      TWorldDim       (physical) world dimension
     110              :  * \tparam      TCondensed      if to shift the scvf ip's to midpoints of the edges
     111              :  */
     112              : template <typename TElem, int TWorldDim, bool TCondensed>
     113            0 : class FV1Geometry_gen : public FVGeometryBase
     114              : {
     115              :         public:
     116              :         ///     type of element
     117              :                 typedef TElem elem_type;
     118              : 
     119              :         ///     type of reference element
     120              :                 typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
     121              : 
     122              :         ///     used traits
     123              :                 typedef fv1_traits<ref_elem_type, TWorldDim> traits;
     124              : 
     125              :         public:
     126              :         ///     dimension of reference element
     127              :                 static const int dim = ref_elem_type::dim;
     128              : 
     129              :         ///     dimension of world
     130              :                 static const int worldDim = TWorldDim;
     131              : 
     132              :         ///     Hanging node flag: this Geometry does not support hanging nodes
     133              :                 static const bool usesHangingNodes = false;
     134              : 
     135              :         /// flag indicating if local data may change
     136              :                 static const bool staticLocalData = true;
     137              :                 
     138              :         ///     whether the scheme shifts the scvf ip's to midpoints of the edges
     139              :                 static const bool condensed_scvf_ips = TCondensed;
     140              : 
     141              :         public:
     142              :         ///     order
     143              :                 static const int order = 1;
     144              : 
     145              :         ///     number of SubControlVolumes
     146              :                 static const size_t numSCV = traits::numSCV;
     147              : 
     148              :         ///     type of SubControlVolume
     149              :                 typedef typename traits::scv_type scv_type;
     150              : 
     151              :         ///     number of SubControlVolumeFaces
     152              :                 static const size_t numSCVF = traits::numSCVF;
     153              : 
     154              :         ///     type of Shape function used
     155              :                 typedef LagrangeP1<ref_elem_type> local_shape_fct_set_type;
     156              : 
     157              :         ///     number of shape functions
     158              :                 static const size_t nsh = local_shape_fct_set_type::nsh;
     159              : 
     160              :         /// number of integration points
     161              :                 static const size_t nip = 1;
     162              : 
     163              :         public:
     164              :         ///     Sub-Control Volume Face structure
     165              :         /**
     166              :          * Each finite element is cut by several sub-control volume faces. The idea
     167              :          * is that the "dual" skeleton formed by the sub control volume faces of
     168              :          * all elements again gives rise to a regular mesh with closed
     169              :          * (lipschitz-bounded) control volumes. The SCVF are the boundary of the
     170              :          * control volume. In computation the flux over each SCVF must be the same
     171              :          * in both directions over the face in order to guarantee the conservation
     172              :          * property.
     173              :          */
     174              :                 class SCVF
     175              :                 {
     176              :                         public:
     177              :                         ///     Number of corners of scvf
     178              :                                 static const size_t numCo =     traits::NumCornersOfSCVF;
     179              : 
     180              :                         public:
     181            0 :                                 SCVF() {}
     182              : 
     183              :                         /// index of SubControlVolume on one side of the scvf
     184            0 :                                 inline size_t from() const {return From;}
     185              : 
     186              :                         /// index of SubControlVolume on one side of the scvf
     187            0 :                                 inline size_t to() const {return To;}
     188              : 
     189              :                         /// normal on scvf (points direction "from"->"to"). Norm is equal to area
     190            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;}
     191              : 
     192              :                         /// number of integration points on scvf
     193            0 :                                 inline size_t num_ip() const {return nip;}
     194              : 
     195              :                         /// local integration point of scvf
     196            0 :                                 inline const MathVector<dim>& local_ip() const {return localIP;}
     197              : 
     198              :                         /// global integration point of scvf
     199            0 :                                 inline const MathVector<worldDim>& global_ip() const {return globalIP;}
     200              : 
     201              :                         /// Transposed Inverse of Jacobian in integration point
     202            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv() const {return JtInv;}
     203              : 
     204              :                         /// Determinant of Jacobian in integration point
     205            0 :                                 inline number detJ() const {return detj;}
     206              : 
     207              :                         /// number of shape functions
     208            0 :                                 inline size_t num_sh() const {return nsh;}
     209              : 
     210              :                         /// value of shape function i in integration point
     211            0 :                                 inline number shape(size_t sh) const {return vShape[sh];}
     212              : 
     213              :                         /// vector of shape functions in ip point
     214            0 :                                 inline const number* shape_vector() const {return vShape;}
     215              : 
     216              :                         /// value of local gradient of shape function i in integration point
     217            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     218            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     219              : 
     220              :                         /// vector of local gradients in ip point
     221            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     222              : 
     223              :                         /// value of global gradient of shape function i in integration point
     224            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     225            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     226              : 
     227              :                         /// vector of global gradients in ip point
     228            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     229              : 
     230              :                         /// number of corners, that bound the scvf
     231            0 :                                 inline size_t num_corners() const {return numCo;}
     232              : 
     233              :                         /// return local corner number i
     234            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     235            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     236              : 
     237              :                         /// return global corner number i
     238            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     239            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     240              : 
     241              :                         private:
     242              :                         //      let outer class access private members
     243              :                                 friend class FV1Geometry_gen<TElem, TWorldDim, TCondensed>;
     244              : 
     245              :                         // This scvf separates the scv with the ids given in "from" and "to"
     246              :                         // The computed normal points in direction from->to
     247              :                                 size_t From, To;
     248              : 
     249              :                         //      The normal on the SCVF pointing (from -> to)
     250              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     251              : 
     252              :                         // ordering is:
     253              :                         // 1D: edgeMidPoint
     254              :                         // 2D: edgeMidPoint, CenterOfElement
     255              :                         // 3D: edgeMidPoint, Side #1, CenterOfElement, Side #2
     256              :                                 MathVector<dim> vLocPos[numCo]; // local corners of scvf
     257              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of scvf
     258              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scvf
     259              : 
     260              :                         // scvf part
     261              :                                 MathVector<dim> localIP; // local integration point
     262              :                                 MathVector<worldDim> globalIP; // global integration point
     263              : 
     264              :                         // shapes and derivatives
     265              :                                 number vShape[nsh]; // shapes at ip
     266              :                                 MathVector<dim> vLocalGrad[nsh]; // local grad at ip
     267              :                                 MathVector<worldDim> vGlobalGrad[nsh]; // global grad at ip
     268              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     269              :                                 number detj; // Jacobian det at ip
     270              :                 };
     271              : 
     272              :         ///     sub control volume structure
     273              :                 class SCV
     274              :                 {
     275              :                         public:
     276              :                         /// Number of corners of scvf
     277              :                                 static const size_t numCo = traits::NumCornersOfSCV;
     278              : 
     279              :                         public:
     280            0 :                                 SCV() {};
     281              : 
     282              :                         /// volume of scv
     283            0 :                                 inline number volume() const {return Vol;}
     284              : 
     285              :                         /// number of corners, that bound the scvf
     286            0 :                                 inline size_t num_corners() const {return numCo;}
     287              : 
     288              :                         /// return local corner number i
     289            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     290            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     291              : 
     292              :                         /// return global corner number i
     293            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     294            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     295              : 
     296              :                         /// return local corners
     297            0 :                                 inline const MathVector<dim>* local_corners() const
     298            0 :                                         {return &vLocPos[0];}
     299              : 
     300              :                         /// return global corners
     301            0 :                                 inline const MathVector<worldDim>* global_corners() const
     302            0 :                                         {return &vGloPos[0];}
     303              : 
     304              :                         /// node id that this scv is associated to
     305            0 :                                 inline size_t node_id() const {return nodeId;}
     306              : 
     307              :                         /// number of integration points
     308            0 :                                 inline size_t num_ip() const {return nip;}
     309              : 
     310              :                         /// local integration point of scv
     311            0 :                                 inline const MathVector<dim>& local_ip() const {return vLocPos[0];}
     312              : 
     313              :                         /// global integration point
     314            0 :                                 inline const MathVector<worldDim>& global_ip() const {return vGloPos[0];}
     315              : 
     316              :                         /// Transposed Inverse of Jacobian in integration point
     317            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv() const {return JtInv;}
     318              : 
     319              :                         /// Determinant of Jacobian in integration point
     320            0 :                                 inline number detJ() const {return detj;}
     321              : 
     322              :                         /// number of shape functions
     323            0 :                                 inline size_t num_sh() const {return nsh;}
     324              : 
     325              :                         /// value of shape function i in integration point
     326            0 :                                 inline number shape(size_t sh) const {return vShape[sh];}
     327              : 
     328              :                         /// vector of shape functions in ip point
     329            0 :                                 inline const number* shape_vector() const {return vShape;}
     330              : 
     331              :                         /// value of local gradient of shape function i in integration point
     332            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     333            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     334              : 
     335              :                         /// vector of local gradients in ip point
     336            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     337              : 
     338              :                         /// value of global gradient of shape function i in integration point
     339            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     340            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     341              : 
     342              :                         /// vector of global gradients in ip point
     343            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     344              : 
     345              :                         private:
     346              :                         //      let outer class access private members
     347              :                                 friend class FV1Geometry_gen<TElem, TWorldDim, TCondensed>;
     348              : 
     349              :                         //  node id of associated node
     350              :                                 size_t nodeId;
     351              : 
     352              :                         //      volume of scv
     353              :                                 number Vol;
     354              : 
     355              :                         //      local and global positions of this element
     356              :                                 MathVector<dim> vLocPos[numCo]; // local position of node
     357              :                                 MathVector<worldDim> vGloPos[numCo]; // global position of node
     358              :                                 MidID midId[numCo]; // dimension and id of object, that's midpoint bounds the scv
     359              : 
     360              :                         // shapes and derivatives
     361              :                                 number vShape[nsh]; // shapes at ip
     362              :                                 MathVector<dim> vLocalGrad[nsh]; // local grad at ip
     363              :                                 MathVector<worldDim> vGlobalGrad[nsh]; // global grad at ip
     364              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     365              :                                 number detj; // Jacobian det at ip
     366              :                 };
     367              : 
     368              :         ///     boundary face
     369              :                 class BF
     370              :                 {
     371              :                         public:
     372              :                         /// Number of corners of bf
     373              :                                 static const size_t numCo =     traits::NumCornersOfBF;
     374              : 
     375              :                         public:
     376            0 :                                 BF() {}
     377              : 
     378              :                         /// index of SubControlVolume of the bf
     379            0 :                                 inline size_t node_id() const {return nodeId;}
     380              : 
     381              :                         /// number of integration points on bf
     382            0 :                                 inline size_t num_ip() const {return nip;}
     383              : 
     384              :                         /// local integration point of bf
     385            0 :                                 inline const MathVector<dim>& local_ip() const {return localIP;}
     386              : 
     387              :                         /// global integration point of bf
     388            0 :                                 inline const MathVector<worldDim>& global_ip() const {return globalIP;}
     389              : 
     390              :                         /// outer normal on bf. Norm is equal to area
     391            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;} // includes area
     392              : 
     393              :                         /// volume of bf
     394            0 :                                 inline number volume() const {return Vol;}
     395              : 
     396              :                         /// Transposed Inverse of Jacobian in integration point
     397            0 :                                 inline const MathMatrix<worldDim, dim>& JTInv() const {return JtInv;}
     398              : 
     399              :                         /// Determinant of Jacobian in integration point
     400            0 :                                 inline number detJ() const {return detj;}
     401              : 
     402              :                         /// number of shape functions
     403            0 :                                 inline size_t num_sh() const {return nsh;}
     404              : 
     405              :                         /// value of shape function i in integration point
     406            0 :                                 inline number shape(size_t sh) const
     407            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vShape[sh];}
     408              : 
     409              :                         /// vector of local gradients in ip point
     410            0 :                                 inline const number* shape_vector() const {return vShape;}
     411              : 
     412              :                         /// value of local gradient of shape function i in integration point
     413            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     414            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     415              : 
     416              :                         /// vector of local gradients in ip point
     417            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     418              : 
     419              :                         /// value of global gradient of shape function i in integration point
     420            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     421            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     422              : 
     423              :                         /// vector of global gradients in ip point
     424            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     425              : 
     426              :                         /// number of corners, that bound the scvf
     427            0 :                                 inline size_t num_corners() const {return numCo;}
     428              : 
     429              :                         /// return local corner number i
     430            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     431            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     432              : 
     433              :                         /// return global corner number i
     434            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     435            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     436              : 
     437              :                         private:
     438              :                         /// let outer class access private members
     439              :                                 friend class FV1Geometry_gen<TElem, TWorldDim, TCondensed>;
     440              : 
     441              :                         //      id of scv this bf belongs to
     442              :                                 size_t nodeId;
     443              : 
     444              :                         // ordering is:
     445              :                         // 1D: edgeMidPoint
     446              :                         // 2D: edgeMidPoint, CenterOfElement
     447              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     448              :                                 MathVector<dim> vLocPos[numCo]; // local corners of bf
     449              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of bf
     450              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the bf
     451              : 
     452              :                         //      scvf part
     453              :                                 MathVector<dim> localIP; // local integration point
     454              :                                 MathVector<worldDim> globalIP; // global integration point
     455              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     456              :                                 number Vol; // volume of bf
     457              : 
     458              :                         //      shapes and derivatives
     459              :                                 number vShape[nsh]; // shapes at ip
     460              :                                 MathVector<dim> vLocalGrad[nsh]; // local grad at ip
     461              :                                 MathVector<worldDim> vGlobalGrad[nsh]; // global grad at ip
     462              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     463              :                                 number detj; // Jacobian det at ip
     464              :                 };
     465              : 
     466              :         public:
     467              :         /// construct object and initialize local values and sizes
     468              :                 FV1Geometry_gen();
     469              : 
     470              :         ///     update local data
     471              :                 void update_local_data();
     472              : 
     473              :         /// update data for given element
     474              :                 void update(GridObject* elem, const MathVector<worldDim>* vCornerCoords,
     475              :                             const ISubsetHandler* ish = NULL);
     476              : 
     477              :         /// update boundary data for given element
     478              :                 void update_boundary_faces(GridObject* elem,
     479              :                                            const MathVector<worldDim>* vCornerCoords,
     480              :                                            const ISubsetHandler* ish = NULL);
     481              : 
     482              :         ///     get the element
     483            0 :                 TElem* elem() const {return m_pElem;}
     484              :                 
     485              :         /// get vector of the global coordinates of corners for current element
     486            0 :                 const MathVector<worldDim>* corners() const {return m_vvGloMid[0];}
     487              : 
     488              :         /// number of SubControlVolumeFaces
     489            0 :                 size_t num_scvf() const {return numSCVF;};
     490              : 
     491              :         /// const access to SubControlVolumeFace number i
     492            0 :                 const SCVF& scvf(size_t i) const
     493            0 :                         {UG_ASSERT(i < num_scvf(), "Invalid Index."); return m_vSCVF[i];}
     494              : 
     495              :         /// number of SubControlVolumes
     496              :                 // do not use this method to obtain the number of shape functions,
     497              :                 // since this is NOT the same for pyramids; use num_sh() instead.
     498            0 :                 size_t num_scv() const {return numSCV;}
     499              : 
     500              :         /// const access to SubControlVolume number i
     501            0 :                 const SCV& scv(size_t i) const
     502            0 :                         {UG_ASSERT(i < num_scv(), "Invalid Index."); return m_vSCV[i];}
     503              : 
     504              :         /// number of shape functions
     505            0 :                 size_t num_sh() const {return nsh;};
     506              : 
     507              :         ///     returns reference object id
     508            0 :                 ReferenceObjectID roid() const {return ref_elem_type::REFERENCE_OBJECT_ID;}
     509              : 
     510              : 
     511              :         public:
     512              :         /// returns number of all scvf ips
     513            0 :                 size_t num_scvf_ips() const {return numSCVF;}
     514              : 
     515              :         /// returns all ips of scvf as they appear in scv loop
     516            0 :                 const MathVector<dim>* scvf_local_ips() const {return m_vLocSCVF_IP;}
     517              : 
     518              :         /// returns all ips of scvf as they appear in scv loop
     519            0 :                 const MathVector<worldDim>* scvf_global_ips() const {return m_vGlobSCVF_IP;}
     520              : 
     521              :         /// returns number of all scv ips
     522            0 :                 size_t num_scv_ips() const {return numSCV;}
     523              : 
     524              :         /// returns all ips of scv as they appear in scv loop
     525            0 :                 const MathVector<dim>* scv_local_ips() const {
     526              :                         if(ref_elem_type::REFERENCE_OBJECT_ID == ROID_PYRAMID || ref_elem_type::REFERENCE_OBJECT_ID == ROID_OCTAHEDRON)
     527            0 :                                 return &(m_vLocSCV_IP[0]);
     528              :                         else
     529            0 :                                 return &(m_vvLocMid[0][0]);
     530              :                 }
     531              : 
     532              :         /// returns all ips of scv as they appear in scv loop
     533            0 :                 const MathVector<worldDim>* scv_global_ips() const {
     534              :                         if(ref_elem_type::REFERENCE_OBJECT_ID == ROID_PYRAMID || ref_elem_type::REFERENCE_OBJECT_ID == ROID_OCTAHEDRON)
     535            0 :                                 return &(m_vGlobSCV_IP[0]);
     536              :                         else
     537            0 :                                 return &(m_vvGloMid[0][0]);
     538              :                 }
     539              : 
     540              :         /// return local coords for node ID
     541            0 :                 const MathVector<dim>& local_node_position(size_t nodeID) const
     542              :                 {
     543              :                         UG_ASSERT(nodeID < (size_t) ref_elem_type::numCorners, "Invalid node id.");
     544            0 :                         return m_vvLocMid[0][nodeID];
     545              :                 }
     546              : 
     547              :         /// return global coords for node ID
     548            0 :                 const MathVector<worldDim>& global_node_position(size_t nodeID) const
     549              :                 {
     550              :                         UG_ASSERT(nodeID < (size_t) ref_elem_type::numCorners, "Invalid node id.");
     551            0 :                         return m_vvGloMid[0][nodeID];
     552              :                 }
     553              : 
     554              :         ///     returns the local coordinates of the center of mass of the element
     555            0 :                 const MathVector<dim>* coe_local() const {return &(m_vvLocMid[dim][0]);}
     556              :                 
     557              :         ///     returns the global coordinates of the center of mass of the element
     558            0 :                 const MathVector<worldDim>* coe_global() const {return &(m_vvGloMid[dim][0]);}
     559              : 
     560              :         protected:
     561              :         //      global and local ips on SCVF
     562              :                 MathVector<worldDim> m_vGlobSCVF_IP[numSCVF];
     563              :                 MathVector<dim> m_vLocSCVF_IP[numSCVF];
     564              : 
     565              :         //      global and local ips on SCV (only needed for Pyramid and Octahedron)
     566              :                 MathVector<worldDim> m_vGlobSCV_IP[numSCV];
     567              :                 MathVector<dim> m_vLocSCV_IP[numSCV];
     568              : 
     569              :         public:
     570              :         /// add subset that is interpreted as boundary subset.
     571            0 :                 inline void add_boundary_subset(int subsetIndex) {m_mapVectorBF[subsetIndex];}
     572              : 
     573              :         /// removes subset that is interpreted as boundary subset.
     574            0 :                 inline void remove_boundary_subset(int subsetIndex) {m_mapVectorBF.erase(subsetIndex);}
     575              : 
     576              :         /// reset all boundary subsets
     577            0 :                 inline void clear_boundary_subsets() {m_mapVectorBF.clear();}
     578              : 
     579              :         /// number of registered boundary subsets
     580            0 :                 inline size_t num_boundary_subsets() {return m_mapVectorBF.size();}
     581              : 
     582              :         /// number of all boundary faces
     583            0 :                 inline size_t num_bf() const
     584              :                 {
     585              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     586              :                         size_t num = 0;
     587            0 :                         for ( it=m_mapVectorBF.begin() ; it != m_mapVectorBF.end(); it++ )
     588            0 :                                 num += (*it).second.size();
     589            0 :                         return num;
     590              :                 }
     591              : 
     592              :         /// number of boundary faces on subset 'subsetIndex'
     593            0 :                 inline size_t num_bf(int si) const
     594              :                 {
     595              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     596              :                         it = m_mapVectorBF.find(si);
     597            0 :                         if(it == m_mapVectorBF.end()) return 0;
     598            0 :                         else return (*it).second.size();
     599              :                 }
     600              : 
     601              :         /// returns the boundary face i for subsetIndex
     602            0 :                 inline const BF& bf(int si, size_t i) const
     603              :                 {
     604              :                         UG_ASSERT(i < num_bf(si), "Invalid index.");
     605              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     606              :                         it = m_mapVectorBF.find(si);
     607            0 :                         if(it == m_mapVectorBF.end()) UG_THROW("FVGeom: No bnd face for subset"<<si);
     608            0 :                         return (*it).second[i];
     609              :                 }
     610              : 
     611              :         /// returns reference to vector of boundary faces for subsetIndex
     612            0 :                 inline const std::vector<BF>& bf(int si) const
     613              :                 {
     614              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     615              :                         it = m_mapVectorBF.find(si);
     616            0 :                         if(it == m_mapVectorBF.end()) return m_vEmptyVectorBF;
     617            0 :                         return (*it).second;
     618              :                 }
     619              : 
     620            0 :                 void reset_curr_elem() {m_pElem = NULL;}
     621              : 
     622              :         protected:
     623              :                 std::map<int, std::vector<BF> > m_mapVectorBF;
     624              :                 std::vector<BF> m_vEmptyVectorBF;
     625              : 
     626              :         private:
     627              :         ///     pointer to current element
     628              :                 TElem* m_pElem;
     629              : 
     630              :         ///     max number of geom objects in all dimensions
     631              :         //      (most objects in 1 dim, i.e. number of edges, but +1 for 1D)
     632              :                 static const int maxMid = numSCVF + 1;
     633              : 
     634              :         ///     local and global geom object midpoints for each dimension
     635              :                 MathVector<dim> m_vvLocMid[dim+1][maxMid];
     636              :                 MathVector<worldDim> m_vvGloMid[dim+1][maxMid];
     637              : 
     638              :         ///     SubControlVolumeFaces
     639              :                 SCVF m_vSCVF[numSCVF];
     640              : 
     641              :         ///     SubControlVolumes
     642              :                 SCV m_vSCV[numSCV];
     643              : 
     644              :         ///     Reference Mapping
     645              :                 ReferenceMapping<ref_elem_type, worldDim> m_mapping;
     646              : 
     647              :         ///     Reference Element
     648              :                 const ref_elem_type& m_rRefElem;
     649              : 
     650              :         ///     Shape function set
     651              :                 const local_shape_fct_set_type& m_rTrialSpace;
     652              : };
     653              : 
     654              : ////////////////////////////////////////////////////////////////////////////////
     655              : // Dim-dependent Finite Volume Geometry
     656              : ////////////////////////////////////////////////////////////////////////////////
     657              : 
     658              : /// Geometry and shape functions for 1st order Vertex-Centered Finite Volume
     659              : /**
     660              :  * \tparam      TDim            reference element dim
     661              :  * \tparam      TWorldDim       (physical) world dimension
     662              :  */
     663              : template <int TDim, int TWorldDim = TDim>
     664            0 : class DimFV1Geometry : public FVGeometryBase
     665              : {
     666              :         public:
     667              :         ///     used traits
     668              :                 typedef fv1_dim_traits<TDim, TWorldDim> traits;
     669              : 
     670              :         public:
     671              :         ///     dimension of reference element
     672              :                 static const int dim = TDim;
     673              : 
     674              :         ///     dimension of world
     675              :                 static const int worldDim = TWorldDim;
     676              : 
     677              :         ///     Hanging node flag: this Geometry does not support hanging nodes
     678              :                 static const bool usesHangingNodes = false;
     679              : 
     680              :         /// flag indicating if local data may change
     681              :                 static const bool staticLocalData = false;
     682              : 
     683              :         public:
     684              :         ///     order
     685              :                 static const int order = 1;
     686              : 
     687              :         ///     number of SubControlVolumes
     688              :                 static const size_t maxNumSCV = traits::maxNumSCV;
     689              : 
     690              :         ///     type of SubControlVolume
     691              :                 typedef typename traits::scv_type scv_type;
     692              : 
     693              :         ///     max number of SubControlVolumeFaces
     694              :                 static const size_t maxNumSCVF = traits::maxNumSCVF;
     695              : 
     696              :         /// max number of shape functions
     697              :                 static const size_t maxNSH = traits::maxNSH;
     698              : 
     699              :         /// number of integration points
     700              :                 static const size_t nip = 1;
     701              : 
     702              :         public:
     703              :         ///     Sub-Control Volume Face structure
     704              :         /**
     705              :          * Each finite element is cut by several sub-control volume faces. The idea
     706              :          * is that the "dual" skeleton formed by the sub control volume faces of
     707              :          * all elements again gives rise to a regular mesh with closed
     708              :          * (lipschitz-bounded) control volumes. The SCVF are the boundary of the
     709              :          * control volume. In computation the flux over each SCVF must be the same
     710              :          * in both directions over the face in order to guarantee the conservation
     711              :          * property.
     712              :          */
     713              :                 class SCVF
     714              :                 {
     715              :                         public:
     716              :                         ///     Number of corners of scvf
     717              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     718              : 
     719              :                         public:
     720            0 :                                 SCVF() {}
     721              : 
     722              :                         /// index of SubControlVolume on one side of the scvf
     723            0 :                                 inline size_t from() const {return From;}
     724              : 
     725              :                         /// index of SubControlVolume on one side of the scvf
     726            0 :                                 inline size_t to() const {return To;}
     727              : 
     728              :                         /// number of integration points on scvf
     729            0 :                                 inline size_t num_ip() const {return nip;}
     730              : 
     731              :                         /// local integration point of scvf
     732            0 :                                 inline const MathVector<dim>& local_ip() const {return localIP;}
     733              : 
     734              :                         /// global integration point of scvf
     735            0 :                                 inline const MathVector<worldDim>& global_ip() const {return globalIP;}
     736              : 
     737              :                         /// normal on scvf (points direction "from"->"to"). Norm is equal to area
     738            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;}
     739              : 
     740              :                         /// Transposed Inverse of Jacobian in integration point
     741            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv() const {return JtInv;}
     742              : 
     743              :                         /// Determinant of Jacobian in integration point
     744            0 :                                 inline number detJ() const {return detj;}
     745              : 
     746              :                         /// number of shape functions
     747            0 :                                 inline size_t num_sh() const {return numSH;}
     748              : 
     749              :                         /// value of shape function i in integration point
     750            0 :                                 inline number shape(size_t sh) const {return vShape[sh];}
     751              : 
     752              :                         /// vector of shape functions in ip point
     753            0 :                                 inline const number* shape_vector() const {return vShape;}
     754              : 
     755              :                         /// value of local gradient of shape function i in integration point
     756            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     757            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     758              : 
     759              :                         /// vector of local gradients in ip point
     760            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     761              : 
     762              :                         /// value of global gradient of shape function i in integration point
     763            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     764            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     765              : 
     766              :                         /// vector of gloabl gradients in ip point
     767            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     768              : 
     769              :                         /// number of corners, that bound the scvf
     770            0 :                                 inline size_t num_corners() const {return numCo;}
     771              : 
     772              :                         /// return local corner number i
     773            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     774            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     775              : 
     776              :                         /// return glbal corner number i
     777            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     778            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     779              : 
     780              :                         private:
     781              :                         //      let outer class access private members
     782              :                                 friend class DimFV1Geometry<dim, worldDim>;
     783              : 
     784              :                         // This scvf separates the scv with the ids given in "from" and "to"
     785              :                         // The computed normal points in direction from->to
     786              :                                 size_t From, To;
     787              : 
     788              :                         //      The normal on the SCVF pointing (from -> to)
     789              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     790              : 
     791              :                         // ordering is:
     792              :                         // 1D: edgeMidPoint
     793              :                         // 2D: edgeMidPoint, CenterOfElement
     794              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     795              :                                 MathVector<dim> vLocPos[numCo]; // local corners of scvf
     796              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of scvf
     797              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scvf
     798              : 
     799              :                         // scvf part
     800              :                                 MathVector<dim> localIP; // local integration point
     801              :                                 MathVector<worldDim> globalIP; // global integration point
     802              : 
     803              :                         // shapes and derivatives
     804              :                                 size_t numSH;
     805              :                                 number vShape[maxNSH]; // shapes at ip
     806              :                                 MathVector<dim> vLocalGrad[maxNSH]; // local grad at ip
     807              :                                 MathVector<worldDim> vGlobalGrad[maxNSH]; // global grad at ip
     808              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     809              :                                 number detj; // Jacobian det at ip
     810              :                 };
     811              : 
     812              :         ///     sub control volume structure
     813              :                 class SCV
     814              :                 {
     815              :                         public:
     816              :                         /// Number of corners of scv
     817              :                                 static const size_t numCo = traits::NumCornersOfSCV;
     818              : 
     819              :                         public:
     820            0 :                                 SCV() {};
     821              : 
     822              :                         /// volume of scv
     823            0 :                                 inline number volume() const {return Vol;}
     824              : 
     825              :                         /// number of corners, that bound the scv
     826            0 :                                 inline size_t num_corners() const {return numCo;}
     827              : 
     828              :                         /// return local corner number i
     829            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     830            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     831              : 
     832              :                         /// return global corner number i
     833            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     834            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     835              : 
     836              :                         /// node id that this scv is associated to
     837            0 :                                 inline size_t node_id() const {return nodeId;}
     838              : 
     839              :                         /// number of integration points
     840            0 :                                 inline size_t num_ip() const {return nip;}
     841              : 
     842              :                         /// local integration point of scv
     843            0 :                                 inline const MathVector<dim>& local_ip() const {return vLocPos[0];}
     844              : 
     845              :                         /// global integration point
     846            0 :                                 inline const MathVector<worldDim>& global_ip() const {return vGloPos[0];}
     847              : 
     848              :                         /// Transposed Inverse of Jacobian in integration point
     849            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv() const {return JtInv;}
     850              : 
     851              :                         /// Determinant of Jacobian in integration point
     852            0 :                                 inline number detJ() const {return detj;}
     853              : 
     854              :                         /// number of shape functions
     855            0 :                                 inline size_t num_sh() const {return numSH;}
     856              : 
     857              :                         /// value of shape function i in integration point
     858            0 :                                 inline number shape(size_t sh) const {return vShape[sh];}
     859              : 
     860              :                         /// vector of shape functions in ip point
     861            0 :                                 inline const number* shape_vector() const {return vShape;}
     862              : 
     863              :                         /// value of local gradient of shape function i in integration point
     864            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     865            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     866              : 
     867              :                         /// vector of local gradients in ip point
     868            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     869              : 
     870              :                         /// value of global gradient of shape function i in integration point
     871            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     872            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     873              : 
     874              :                         /// vector of global gradients in ip point
     875            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     876              : 
     877              :                         private:
     878              :                         //      let outer class access private members
     879              :                                 friend class DimFV1Geometry<dim, worldDim>;
     880              : 
     881              :                         //  node id of associated node
     882              :                                 size_t nodeId;
     883              : 
     884              :                         //      volume of scv
     885              :                                 number Vol;
     886              : 
     887              :                         //      local and global positions of this element
     888              :                                 MathVector<dim> vLocPos[numCo]; // local position of node
     889              :                                 MathVector<worldDim> vGloPos[numCo]; // global position of node
     890              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scv
     891              : 
     892              :                         // shapes and derivatives
     893              :                                 size_t numSH;
     894              :                                 number vShape[maxNSH]; // shapes at ip
     895              :                                 MathVector<dim> vLocalGrad[maxNSH]; // local grad at ip
     896              :                                 MathVector<worldDim> vGlobalGrad[maxNSH]; // global grad at ip
     897              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     898              :                                 number detj; // Jacobian det at ip
     899              :                 };
     900              : 
     901              :         ///     boundary face
     902              :                 class BF
     903              :                 {
     904              :                         public:
     905              :                         /// Number of corners of bf
     906              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     907              : 
     908              :                         public:
     909            0 :                                 BF() {}
     910              : 
     911              :                         /// index of SubControlVolume of the bf
     912            0 :                                 inline size_t node_id() const {return nodeId;}
     913              : 
     914              :                         /// number of integration points on bf
     915            0 :                                 inline size_t num_ip() const {return nip;}
     916              : 
     917              :                         /// local integration point of bf
     918            0 :                                 inline const MathVector<dim>& local_ip() const {return localIP;}
     919              : 
     920              :                         /// global integration point of bf
     921            0 :                                 inline const MathVector<worldDim>& global_ip() const {return globalIP;}
     922              : 
     923              :                         /// outer normal on bf. Norm is equal to area
     924            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;} // includes area
     925              : 
     926              :                         /// volume of bf
     927            0 :                                 inline number volume() const {return Vol;}
     928              : 
     929              :                         /// Transposed Inverse of Jacobian in integration point
     930            0 :                                 inline const MathMatrix<worldDim, dim>& JTInv() const {return JtInv;}
     931              : 
     932              :                         /// Determinant of Jacobian in integration point
     933            0 :                                 inline number detJ() const {return detj;}
     934              : 
     935              :                         /// number of shape functions
     936            0 :                                 inline size_t num_sh() const {return numSH;}
     937              : 
     938              :                         /// value of shape function i in integration point
     939            0 :                                 inline number shape(size_t sh) const
     940            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vShape[sh];}
     941              : 
     942              :                         /// vector of local gradients in ip point
     943            0 :                                 inline const number* shape_vector() const {return vShape;}
     944              : 
     945              :                         /// value of local gradient of shape function i in integration point
     946            0 :                                 inline const MathVector<dim>& local_grad(size_t sh) const
     947            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vLocalGrad[sh];}
     948              : 
     949              :                         /// vector of local gradients in ip point
     950            0 :                                 inline const MathVector<dim>* local_grad_vector() const {return vLocalGrad;}
     951              : 
     952              :                         /// value of global gradient of shape function i in integration point
     953            0 :                                 inline const MathVector<worldDim>& global_grad(size_t sh) const
     954            0 :                                         {UG_ASSERT(sh < num_sh(), "Invalid index"); return vGlobalGrad[sh];}
     955              : 
     956              :                         /// vector of global gradients in ip point
     957            0 :                                 inline const MathVector<worldDim>* global_grad_vector() const {return vGlobalGrad;}
     958              : 
     959              :                         /// number of corners, that bound the scvf
     960            0 :                                 inline size_t num_corners() const {return numCo;}
     961              : 
     962              :                         /// return local corner number i
     963            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     964            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     965              : 
     966              :                         /// return global corner number i
     967            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     968            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     969              : 
     970              :                         private:
     971              :                         /// let outer class access private members
     972              :                                 friend class DimFV1Geometry<dim, worldDim>;
     973              : 
     974              :                         //      id of scv this bf belongs to
     975              :                                 size_t nodeId;
     976              : 
     977              :                         // ordering is:
     978              :                         // 1D: edgeMidPoint
     979              :                         // 2D: edgeMidPoint, CenterOfElement
     980              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     981              :                                 MathVector<dim> vLocPos[numCo]; // local corners of bf
     982              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of bf
     983              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the bf
     984              : 
     985              :                         //      scvf part
     986              :                                 MathVector<dim> localIP; // local integration point
     987              :                                 MathVector<worldDim> globalIP; // global integration point
     988              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     989              :                                 number Vol; // volume of bf
     990              : 
     991              :                         //      shapes and derivatives
     992              :                                 size_t numSH;
     993              :                                 number vShape[maxNSH]; // shapes at ip
     994              :                                 MathVector<dim> vLocalGrad[maxNSH]; // local grad at ip
     995              :                                 MathVector<worldDim> vGlobalGrad[maxNSH]; // global grad at ip
     996              :                                 MathMatrix<worldDim,dim> JtInv; // Jacobian transposed at ip
     997              :                                 number detj; // Jacobian det at ip
     998              :                 };
     999              : 
    1000              :         public:
    1001              :         /// construct object and initialize local values and sizes
    1002            0 :                 DimFV1Geometry() : m_pElem(NULL), m_roid(ROID_UNKNOWN) {};
    1003              : 
    1004              :         /// update data for given element
    1005              :                 void update(GridObject* elem, const MathVector<worldDim>* vCornerCoords,
    1006              :                             const ISubsetHandler* ish = NULL);
    1007              : 
    1008              :         /// update boundary data for given element
    1009              :                 void update_boundary_faces(GridObject* elem,
    1010              :                                            const MathVector<worldDim>* vCornerCoords,
    1011              :                                            const ISubsetHandler* ish = NULL);
    1012              : 
    1013              :         ///     get the element
    1014            0 :                 GridObject* elem() const {return m_pElem;}
    1015              :                 
    1016              :         /// get vector of corners for current element
    1017            0 :                 const MathVector<worldDim>* corners() const {return m_vvGloMid[0];}
    1018              : 
    1019              :         /// number of SubControlVolumeFaces
    1020            0 :                 size_t num_scvf() const {return m_numSCVF;};
    1021              : 
    1022              :         /// const access to SubControlVolumeFace number i
    1023            0 :                 const SCVF& scvf(size_t i) const
    1024            0 :                         {UG_ASSERT(i < num_scvf(), "Invalid Index."); return m_vSCVF[i];}
    1025              : 
    1026              :         /// number of SubControlVolumes
    1027              :                 // do not use this method to obtain the number of shape functions,
    1028              :                 // since this is NOT the same for pyramids; use num_sh() instead.
    1029            0 :                 size_t num_scv() const {return m_numSCV;}
    1030              : 
    1031              :         /// const access to SubControlVolume number i
    1032            0 :                 const SCV& scv(size_t i) const
    1033            0 :                         {UG_ASSERT(i < num_scv(), "Invalid Index."); return m_vSCV[i];}
    1034              : 
    1035              :         /// number of shape functions
    1036            0 :                 size_t num_sh() const {return m_nsh;};
    1037              : 
    1038              :         public:
    1039              :         /// returns number of all scvf ips
    1040            0 :                 size_t num_scvf_ips() const {return m_numSCVF;}
    1041              : 
    1042              :         /// returns all ips of scvf as they appear in scv loop
    1043            0 :                 const MathVector<dim>* scvf_local_ips() const {return m_vLocSCVF_IP;}
    1044              : 
    1045              :         /// returns all ips of scvf as they appear in scv loop
    1046            0 :                 const MathVector<worldDim>* scvf_global_ips() const {return m_vGlobSCVF_IP;}
    1047              : 
    1048              :         /// returns number of all scv ips
    1049            0 :                 size_t num_scv_ips() const {return m_numSCV;}
    1050              : 
    1051              :         /// returns all ips of scv as they appear in scv loop
    1052            0 :                 const MathVector<dim>* scv_local_ips() const {
    1053            0 :                         if(m_roid == ROID_PYRAMID || m_roid == ROID_OCTAHEDRON)
    1054            0 :                                 return &(m_vLocSCV_IP[0]);
    1055              :                         else
    1056            0 :                                 return &(m_vvLocMid[0][0]);
    1057              :                 }
    1058              : 
    1059              :         /// returns all ips of scv as they appear in scv loop
    1060            0 :                 const MathVector<worldDim>* scv_global_ips() const {
    1061            0 :                         if(m_roid == ROID_PYRAMID || m_roid == ROID_OCTAHEDRON)
    1062            0 :                                 return &(m_vGlobSCV_IP[0]);
    1063              :                         else
    1064            0 :                                 return &(m_vvGloMid[0][0]);
    1065              :                 }
    1066              : 
    1067              :         /// return local coords for node ID
    1068            0 :                 const MathVector<dim>& local_node_position(size_t nodeID) const
    1069              :                 {
    1070              :                         UG_ASSERT(nodeID < (size_t) maxMid, "Invalid node id.");
    1071            0 :                         return m_vvLocMid[0][nodeID];
    1072              :                 }
    1073              : 
    1074              :         /// return global coords for node ID
    1075            0 :                 const MathVector<worldDim>& global_node_position(size_t nodeID) const
    1076              :                 {
    1077              :                         UG_ASSERT(nodeID < (size_t) maxMid, "Invalid node id.");
    1078            0 :                         return m_vvGloMid[0][nodeID];
    1079              :                 }
    1080              : 
    1081              :         ///     returns the local coordinates of the center of mass of the element
    1082            0 :                 const MathVector<dim>* coe_local() const {return &(m_vvLocMid[dim][0]);}
    1083              :                 
    1084              :         ///     returns the global coordinates of the center of mass of the element
    1085            0 :                 const MathVector<worldDim>* coe_global() const {return &(m_vvGloMid[dim][0]);}
    1086              : 
    1087              :         ///     returns reference object id
    1088            0 :                 ReferenceObjectID roid() const {return m_roid;}
    1089              : 
    1090              :         ///     update local data
    1091              :                 void update_local(ReferenceObjectID roid);
    1092              : 
    1093              :         protected:
    1094              :         //      global and local ips on SCVF
    1095              :                 MathVector<worldDim> m_vGlobSCVF_IP[maxNumSCVF];
    1096              :                 MathVector<dim> m_vLocSCVF_IP[maxNumSCVF];
    1097              : 
    1098              :         //      global and local ips on SCV (only needed for Pyramid and Octahedron)
    1099              :                 MathVector<worldDim> m_vGlobSCV_IP[maxNumSCV];
    1100              :                 MathVector<dim> m_vLocSCV_IP[maxNumSCV];
    1101              : 
    1102              :         public:
    1103              :         /// add subset that is interpreted as boundary subset.
    1104            0 :                 inline void add_boundary_subset(int subsetIndex) {m_mapVectorBF[subsetIndex];}
    1105              : 
    1106              :         /// removes subset that is interpreted as boundary subset.
    1107            0 :                 inline void remove_boundary_subset(int subsetIndex) {m_mapVectorBF.erase(subsetIndex);}
    1108              : 
    1109              :         /// reset all boundary subsets
    1110            0 :                 inline void clear_boundary_subsets() {m_mapVectorBF.clear();}
    1111              : 
    1112              :         /// number of registered boundary subsets
    1113            0 :                 inline size_t num_boundary_subsets() {return m_mapVectorBF.size();}
    1114              : 
    1115              :         /// number of all boundary faces
    1116            0 :                 inline size_t num_bf() const
    1117              :                 {
    1118              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1119              :                         size_t num = 0;
    1120            0 :                         for ( it=m_mapVectorBF.begin() ; it != m_mapVectorBF.end(); it++ )
    1121            0 :                                 num += (*it).second.size();
    1122            0 :                         return num;
    1123              :                 }
    1124              : 
    1125              :         /// number of boundary faces on subset 'subsetIndex'
    1126            0 :                 inline size_t num_bf(int si) const
    1127              :                 {
    1128              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1129              :                         it = m_mapVectorBF.find(si);
    1130            0 :                         if(it == m_mapVectorBF.end()) return 0;
    1131            0 :                         else return (*it).second.size();
    1132              :                 }
    1133              : 
    1134              :         /// returns the boundary face i for subsetIndex
    1135            0 :                 inline const BF& bf(int si, size_t i) const
    1136              :                 {
    1137              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1138              :                         it = m_mapVectorBF.find(si);
    1139            0 :                         if(it == m_mapVectorBF.end()) UG_THROW("DimFV1Geom: No BndSubset "<<si);
    1140            0 :                         return (*it).second[i];
    1141              :                 }
    1142              : 
    1143              :         /// returns reference to vector of boundary faces for subsetIndex
    1144            0 :                 inline const std::vector<BF>& bf(int si) const
    1145              :                 {
    1146              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1147              :                         it = m_mapVectorBF.find(si);
    1148            0 :                         if(it == m_mapVectorBF.end()) return m_vEmptyVectorBF;
    1149            0 :                         return (*it).second;
    1150              :                 }
    1151              : 
    1152              :         protected:
    1153              :                 std::map<int, std::vector<BF> > m_mapVectorBF;
    1154              :                 std::vector<BF> m_vEmptyVectorBF;
    1155              : 
    1156              :         private:
    1157              :         ///     pointer to current element
    1158              :                 GridObject* m_pElem;
    1159              : 
    1160              :         ///     current reference object id
    1161              :                 ReferenceObjectID m_roid;
    1162              : 
    1163              :         ///     current number of scv
    1164              :                 size_t m_numSCV;
    1165              : 
    1166              :         ///     current number of scvf
    1167              :                 size_t m_numSCVF;
    1168              : 
    1169              :         /// current number of shape functions
    1170              :                 size_t m_nsh;
    1171              : 
    1172              :         ///     max number of geometric objects in a dimension
    1173              :         //      (most objects in 1 dim, i.e. number of edges, but +1 for 1D)
    1174              :                 static const int maxMid = maxNumSCVF + 1;
    1175              : 
    1176              :         ///     local and global geom object midpoints for each dimension
    1177              :                 MathVector<dim> m_vvLocMid[dim+1][maxMid];
    1178              :                 MathVector<worldDim> m_vvGloMid[dim+1][maxMid];
    1179              : 
    1180              :         ///     SubControlVolumeFaces
    1181              :                 SCVF m_vSCVF[maxNumSCVF];
    1182              : 
    1183              :         ///     SubControlVolumes
    1184              :                 SCV m_vSCV[maxNumSCV];
    1185              : };
    1186              : 
    1187              : 
    1188              : ////////////////////////////////////////////////////////////////////////////////
    1189              : // FV1 Manifold Geometry
    1190              : ////////////////////////////////////////////////////////////////////////////////
    1191              : 
    1192              : template <typename TElem, int TWorldDim>
    1193              : class FV1ManifoldGeometry
    1194              : {
    1195              :         public:
    1196              :         //      type of element
    1197              :                 typedef TElem elem_type;
    1198              : 
    1199              :         //      type of reference element
    1200              :                 typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
    1201              : 
    1202              :         public:
    1203              :         //      order
    1204              :                 static const int order = 1;
    1205              : 
    1206              :         //      number of BoundaryFaces
    1207              :                 static const size_t m_numBF = ref_elem_type::numCorners;
    1208              :                 
    1209              :         //      dimension of reference element
    1210              :                 static const int dim = ref_elem_type::dim;
    1211              :                 
    1212              :         //      dimension of world
    1213              :                 static const int worldDim = TWorldDim;
    1214              : 
    1215              :         //      type of BoundaryFaces
    1216              :                 typedef typename fv1_traits<ref_elem_type, dim>::scv_type bf_type;
    1217              : 
    1218              :         //      Hanging node flag: this Geometry does not support hanging nodes
    1219              :                 static const bool usesHangingNodes = false;
    1220              : 
    1221              :         /// flag indicating if local data may change
    1222              :                 static const bool staticLocalData = true;
    1223              : 
    1224              :         protected:
    1225              :                 struct MidID
    1226              :                 {
    1227            0 :                                 MidID() : dim(0), id(0) {};
    1228            0 :                                 MidID(size_t dim_, size_t id_) : dim(dim_), id(id_) {};
    1229              :                                 size_t dim;
    1230              :                                 size_t id;
    1231              :                 };
    1232              :                 
    1233              :         public: 
    1234            0 :                 class BF
    1235              :                 {
    1236              :                         private:
    1237              :                         //      let outer class access private members
    1238              :                                 friend class FV1ManifoldGeometry<TElem, TWorldDim>;
    1239              : 
    1240              :                         //      number of integration points
    1241              :                                 static const size_t m_numIP = 1;
    1242              :                                 
    1243              :                         //      max number of corners of bf
    1244              :                                 static const size_t numCorners = fv1_traits<ref_elem_type, dim>::NumCornersOfSCV;
    1245              : 
    1246              :                         public:
    1247            0 :                                 BF() {};
    1248              : 
    1249              :                         /// node id that this bf is associated to
    1250            0 :                                 inline size_t node_id() const {return nodeId;}
    1251              : 
    1252              :                         /// number of integration points
    1253            0 :                                 inline size_t num_ip() const {return m_numIP;}
    1254              : 
    1255              :                         /// local integration point of bf
    1256            0 :                                 inline const MathVector<dim>& local_ip() const
    1257            0 :                                 {return vLocPos[0];}    // <-- always the vertex
    1258              : 
    1259              :                         /// global integration point
    1260            0 :                                 inline const MathVector<worldDim>& global_ip() const
    1261            0 :                                 {return vGloPos[0];}    // <-- here too
    1262              : 
    1263              :                         /// volume of bf
    1264            0 :                                 inline number volume() const {return vol;}
    1265              : 
    1266              :                         /// number of corners, that bound the bf
    1267            0 :                                 inline size_t num_corners() const {return numCorners;}
    1268              : 
    1269              :                         /// return local position of corner number i
    1270            0 :                                 inline const MathVector<dim>& local_corner(size_t i) const
    1271            0 :                                         {UG_ASSERT(i < num_corners(), "Invalid index."); return vLocPos[i];}
    1272              : 
    1273              :                         /// return global position of corner number i
    1274            0 :                                 inline const MathVector<worldDim>& global_corner(size_t i) const
    1275            0 :                                         {UG_ASSERT(i < num_corners(), "Invalid index."); return vGloPos[i];}
    1276              :                                 
    1277              :                         /// number of shape functions
    1278            0 :                                 inline size_t num_sh() const {return vShape.size();}
    1279              : 
    1280              :                         /// value of shape function i in integration point
    1281            0 :                                 inline number shape(size_t i, size_t ip) const
    1282            0 :                                         {UG_ASSERT(ip < num_ip(), "Invalid index"); return vShape[i];}
    1283              :                                 
    1284              :                         private:
    1285              :                                 size_t nodeId;                                                                          // id of associated node
    1286              :                                 
    1287              :                                 // CORNERS: ordering is:
    1288              :                                 // 1D: edgeMidPoint, CenterOfElement
    1289              :                                 // 2D: edgeMidPoint, Side one, CenterOfElement, Side two
    1290              :                                 MathVector<dim> vLocPos[numCorners];                      // local position of node
    1291              :                                 MathVector<worldDim> vGloPos[numCorners]; // global position of node
    1292              :                                 MidID midId[numCorners];                        // dimension and id of object, whose midpoint bounds the scv
    1293              :                                 
    1294              :                                 // IPs & shapes
    1295              :                                 std::vector<number> vShape; // shapes at ip
    1296              :                                 
    1297              :                                 number vol;
    1298              :                 };
    1299              :         
    1300              :         protected:
    1301            0 :                 void copy_local_corners(BF& bf)
    1302              :                 {
    1303            0 :                         for (size_t i = 0; i < bf.num_corners(); ++i)
    1304              :                         {
    1305            0 :                                 const size_t dim = bf.midId[i].dim;
    1306            0 :                                 const size_t id = bf.midId[i].id;
    1307              :                                 bf.vLocPos[i] = m_locMid[dim][id];
    1308              :                         }
    1309            0 :                 }
    1310              :                 
    1311            0 :                 void copy_global_corners(BF& bf)
    1312              :                 {
    1313            0 :                         for (size_t i = 0; i < bf.num_corners(); ++i)
    1314              :                         {
    1315            0 :                                 const size_t dim = bf.midId[i].dim;
    1316            0 :                                 const size_t id = bf.midId[i].id;
    1317              :                                 bf.vGloPos[i] = m_gloMid[dim][id];
    1318              :                         }
    1319            0 :                 }
    1320              : 
    1321              :                 std::vector<MathVector<dim> > m_vLocBFIP;
    1322              :                 std::vector<MathVector<worldDim> > m_vGlobBFIP;
    1323              :                 
    1324              :                 
    1325              :         public:
    1326              :         /// constructor
    1327              :                 FV1ManifoldGeometry();
    1328              :                 
    1329              :         ///     update data for given element
    1330              :                 void update(GridObject* elem, const MathVector<worldDim>* vCornerCoords,
    1331              :                             const ISubsetHandler* ish = NULL);
    1332              :                         
    1333              :         ///     get the element
    1334            0 :                 GridObject* elem() const {return m_pElem;}
    1335              :                 
    1336              :         /// get vector of corners for current element
    1337            0 :                 const MathVector<worldDim>* corners() const {return m_gloMid[0];}
    1338              : 
    1339              :         /// number of BoundaryFaces
    1340            0 :                 inline size_t num_bf() const {return m_numBF;}
    1341              : 
    1342              :         /// const access to Boundary Face number i
    1343            0 :                 inline const BF& bf(size_t i) const
    1344            0 :                         {UG_ASSERT(i < num_bf(), "Invalid Index."); return m_vBF[i];}
    1345              :         
    1346              :         /// returns all ips of scvf as they appear in scv loop
    1347            0 :                 const MathVector<worldDim>* bf_global_ips() const {return &m_vGlobBFIP[0];}
    1348              : 
    1349              :         /// returns number of all BF ips
    1350            0 :                 size_t num_bf_global_ips() const {return m_vGlobBFIP.size();}
    1351              : 
    1352              :         /// returns all ips of BF as they appear in scv loop
    1353            0 :                 const MathVector<dim>* bf_local_ips() const {return &m_vLocBFIP[0];}
    1354              : 
    1355              :         /// returns number of all BF ips
    1356            0 :                 size_t num_bf_local_ips() const {return m_vLocBFIP.size();}
    1357              : 
    1358              :         private:
    1359              :         //      pointer to current element
    1360              :                 GridObject* m_pElem;
    1361              :                 
    1362              :         //      local and global geom object midpoints for each dimension
    1363              :                 MathVector<dim> m_locMid[dim+1][m_numBF];
    1364              :                 MathVector<worldDim> m_gloMid[dim+1][m_numBF];
    1365              :                 
    1366              :         //      BndFaces
    1367              :                 BF m_vBF[m_numBF];
    1368              :                 
    1369              :         //      Reference Mapping
    1370              :                 ReferenceMapping<ref_elem_type, worldDim> m_rMapping;
    1371              : 
    1372              :         //      Reference Element
    1373              :                 const ref_elem_type& m_rRefElem;
    1374              : };
    1375              : 
    1376              : }
    1377              : 
    1378              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FV1_GEOMETRY__ */
        

Generated by: LCOV version 2.0-1