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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-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__FINITE_VOLUME_HIGHER_ORDER_GEOMETRY__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_VOLUME_HIGHER_ORDER_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/quadrature/gauss/gauss_quad.h"
      52              : #include "fv_util.h"
      53              : #include "fv_geom_base.h"
      54              : 
      55              : namespace ug{
      56              : 
      57              : ////////////////////////////////////////////////////////////////////////////////
      58              : // FV Geometry for Reference Element Type (all orders)
      59              : ////////////////////////////////////////////////////////////////////////////////
      60              : 
      61              : /// Geometry and shape functions for any order Vertex-Centered Finite Volume
      62              : /**
      63              :  * \tparam      TOrder                  order
      64              :  * \tparam      TElem                   Element type
      65              :  * \tparam      TWorldDim               (physical) world dimension
      66              :  * \tparam      TQuadOrderSCVF  integration order for scvf
      67              :  * \tparam      TQuadOrderSCV   integration order for scv
      68              :  */
      69              : template <   int TOrder, typename TElem, int TWorldDim,
      70              :                         int TQuadOrder = TOrder + 1>
      71              : class FVGeometry : public FVGeometryBase
      72              : {
      73              :         private:
      74              :         ///     small abbreviation for order
      75              :                 static const int p = TOrder;
      76              : 
      77              :         public:
      78              :         ///     type of element
      79              :                 typedef TElem elem_type;
      80              : 
      81              :         ///     type of reference element
      82              :                 typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
      83              : 
      84              :         ///     dimension of reference element
      85              :                 static const int dim = ref_elem_type::dim;
      86              : 
      87              :         ///     dimension of world
      88              :                 static const int worldDim = TWorldDim;
      89              : 
      90              :         public:
      91              :         ///     order
      92              :                 static const int order = TOrder;
      93              : 
      94              :         ///     number of subelements
      95              :                 static const size_t numSubElem = Pow<p, dim>::value;
      96              : 
      97              : 
      98              :         ///     traits used
      99              :                 typedef fv1_traits<ref_elem_type, worldDim> traits;
     100              : 
     101              :         ///     type of SubControlVolumeFace
     102              :                 typedef typename traits::scvf_type scvf_type;
     103              : 
     104              :         ///     number of SCVF per SubElement
     105              :                 static const size_t numSCVFPerSubElem = ref_elem_type::numEdges;
     106              : 
     107              :         ///     number of SubControlVolumeFaces
     108              :                 static const size_t numSCVF = numSubElem * numSCVFPerSubElem;
     109              : 
     110              :         ///     quadrature order
     111              :                 static const int quadOrderSCVF = TQuadOrder;
     112              : 
     113              :         ///     type of quadrature rule
     114              :                 typedef GaussQuadrature<scvf_type, quadOrderSCVF> scvf_quad_rule_type;
     115              : 
     116              :         ///     number of scvf ip
     117              :                 static const size_t numSCVFIP = scvf_quad_rule_type::nip * numSCVF;
     118              : 
     119              : 
     120              :         ///     type of SubControlVolume
     121              :                 typedef typename traits::scv_type scv_type;
     122              : 
     123              :         ///     number of SCV per SubElement
     124              :                 static const size_t numSCVPerSubElem = ref_elem_type::numCorners;
     125              : 
     126              :         ///     number of SubControlVolumes
     127              :                 static const size_t numSCV = numSubElem * numSCVPerSubElem;
     128              : 
     129              :         ///     quadrature order
     130              :                 static const int quadOrderSCV = TQuadOrder;
     131              : 
     132              :         ///     type of quadrature rule
     133              :                 typedef GaussQuadrature<scv_type, quadOrderSCV> scv_quad_rule_type;
     134              : 
     135              :         ///     number of scv ip
     136              :                 static const size_t numSCVIP = scv_quad_rule_type::nip * numSCV;
     137              : 
     138              : 
     139              :         /// type of Shape function used
     140              :                 typedef LagrangeLSFS<ref_elem_type, p> local_shape_fct_set_type;
     141              : 
     142              :         ///     number of shape functions
     143              :                 static const size_t nsh = local_shape_fct_set_type::nsh;
     144              : 
     145              :         ///     Hanging node flag: this Geometry does not support hanging nodes
     146              :                 static const bool usesHangingNodes = false;
     147              : 
     148              :         /// flag indicating if local data may change
     149              :                 static const bool staticLocalData = true;
     150              : 
     151              :         public:
     152              :         ///     Sub-Control Volume Face structure
     153              :                 class SCVF
     154              :                 {
     155              :                         public:
     156              :                         ///     Number of integration points
     157              :                                 static const size_t nip = scvf_quad_rule_type::nip;
     158              : 
     159              :                         ///     Number of corners of scvf
     160              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     161              : 
     162              :                         public:
     163            0 :                                 SCVF() {}
     164              : 
     165              :                         /// index of SubControlVolume on one side of the scvf
     166            0 :                                 inline size_t from() const {return From;}
     167              : 
     168              :                         /// index of SubControlVolume on one side of the scvf
     169            0 :                                 inline size_t to() const {return To;}
     170              : 
     171              :                         /// number of integration points on scvf
     172            0 :                                 inline size_t num_ip() const {return nip;}
     173              : 
     174              :                         ///     integration weight
     175            0 :                                 inline number weight(size_t ip) const
     176            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip]*vDetJMap[ip];;}
     177              : 
     178              :                         /// local integration point of scvf
     179            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     180            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     181              : 
     182              :                         /// global integration point of scvf
     183            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     184            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     185              : 
     186              :                         /// normal on scvf (points direction "from"->"to"), normalized
     187            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;}
     188              : 
     189              :                         /// Transposed Inverse of Jacobian in integration point
     190            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     191            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vJtInv[ip];}
     192              : 
     193              :                         /// Determinant of Jacobian in integration point
     194            0 :                                 inline number detJ(size_t ip) const
     195            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip];}
     196              : 
     197              :                         /// number of shape functions
     198            0 :                                 inline size_t num_sh() const {return nsh;}
     199              : 
     200              :                         /// value of shape function i in integration point
     201            0 :                                 inline number shape(size_t ip, size_t sh) const
     202            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip][sh];}
     203              : 
     204              :                         /// vector of shape functions in ip point
     205            0 :                                 inline const number* shape_vector(size_t ip) const
     206            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip];}
     207              : 
     208              :                         /// value of local gradient of shape function i in integration point
     209            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     210              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     211            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip][sh];}
     212              : 
     213              :                         /// vector of local gradients in ip point
     214            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     215            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip];}
     216              : 
     217              :                         /// value of global gradient of shape function i in integration point
     218            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     219              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     220            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip][sh];}
     221              : 
     222              :                         /// vector of global gradients in ip point
     223            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     224            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip];}
     225              : 
     226              :                         /// number of corners, that bound the scvf
     227            0 :                                 inline size_t num_corners() const {return numCo;}
     228              : 
     229              :                         /// return local corner number i
     230            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     231            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     232              : 
     233              :                         /// return global corner number i
     234            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     235            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     236              : 
     237              :                         private:
     238              :                         //      let outer class access private members
     239              :                                 friend class FVGeometry<TOrder, TElem, TWorldDim, TQuadOrder>;
     240              : 
     241              :                         // This scvf separates the scv with the ids given in "from" and "to"
     242              :                         // The computed normal points in direction from->to
     243              :                                 size_t From, To;
     244              : 
     245              :                         //      The normal on the SCVF pointing (from -> to)
     246              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     247              : 
     248              :                         // ordering is:
     249              :                         // 1D: edgeMidPoint
     250              :                         // 2D: edgeMidPoint, CenterOfElement
     251              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     252              :                                 MathVector<dim> vLocPos[numCo]; // local corners of scvf
     253              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of scvf
     254              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scvf
     255              : 
     256              :                         // scvf part
     257              :                                 MathVector<dim> vLocalIP[nip]; // local integration point
     258              :                                 MathVector<worldDim> vGlobalIP[nip]; // global integration point
     259              :                                 const number* vWeight; // weight at ip
     260              : 
     261              :                         // shapes and derivatives
     262              :                                 number vvShape[nip][nsh]; // shapes at ip
     263              :                                 MathVector<dim> vvLocalGrad[nip][nsh]; // local grad at ip
     264              :                                 MathVector<worldDim> vvGlobalGrad[nip][nsh]; // global grad at ip
     265              :                                 MathMatrix<worldDim,dim> vJtInv[nip]; // Jacobian transposed at ip
     266              :                                 number vDetJ[nip]; // Jacobian det at ip
     267              :                                 number vDetJMap[nip]; // Jacobian det at ip
     268              :                 };
     269              : 
     270              :         ///     sub control volume structure
     271              :                 class SCV
     272              :                 {
     273              :                         public:
     274              :                         ///     Number of integration points
     275              :                                 static const size_t nip = scv_quad_rule_type::nip;
     276              : 
     277              :                         /// Number of corners of scvf
     278              :                                 static const size_t numCo =     traits::NumCornersOfSCV;
     279              : 
     280              :                         public:
     281            0 :                                 SCV() {};
     282              : 
     283              :                         /// number of corners, that bound the scvf
     284            0 :                                 inline size_t num_corners() const {return numCo;}
     285              : 
     286              :                         /// return local corner number i
     287            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     288            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     289              : 
     290              :                         /// return glbal corner number i
     291            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     292            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     293              : 
     294              :                         /// node id that this scv is associated to
     295            0 :                                 inline size_t node_id() const {return nodeId;}
     296              : 
     297              :                         /// number of integration points
     298            0 :                                 inline size_t num_ip() const {return nip;}
     299              : 
     300              :                         ///     weigth of integration point
     301            0 :                                 inline number weight(size_t ip) const
     302            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip]*vDetJMap[ip];}
     303              : 
     304              :                         /// local integration point of scv
     305            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     306            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     307              : 
     308              :                         /// global integration point
     309            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     310            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     311              : 
     312              :                         /// Transposed Inverse of Jacobian in integration point
     313            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     314            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vJtInv[ip];}
     315              : 
     316              :                         /// Determinant of Jacobian in integration point
     317            0 :                                 inline number detJ(size_t ip) const
     318            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vDetJ[ip];}
     319              : 
     320              :                         /// number of shape functions
     321            0 :                                 inline size_t num_sh() const {return nsh;}
     322              : 
     323              :                         /// value of shape function i in integration point
     324            0 :                                 inline number shape(size_t ip, size_t sh) const
     325            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vvShape[ip][sh];}
     326              : 
     327              :                         /// vector of shape functions in ip point
     328            0 :                                 inline const number* shape_vector(size_t ip) const
     329            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vvShape[ip];}
     330              : 
     331              :                         /// value of local gradient of shape function i in integration point
     332            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     333              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     334            0 :                                          UG_ASSERT(ip<num_ip(),"Wring index."); return vvLocalGrad[ip][sh];}
     335              : 
     336              :                         /// vector of local gradients in ip point
     337            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     338            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vvLocalGrad[ip];}
     339              : 
     340              :                         /// value of global gradient of shape function i in integration point
     341            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     342              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     343            0 :                                          UG_ASSERT(ip<num_ip(),"Wring index."); return vvGlobalGrad[ip][sh];}
     344              : 
     345              :                         /// vector of global gradients in ip point
     346            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     347            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vvGlobalGrad[ip];}
     348              : 
     349              :                         private:
     350              :                         //      let outer class access private members
     351              :                                 friend class FVGeometry<TOrder, TElem, TWorldDim, TQuadOrder>;
     352              : 
     353              :                         //  node id of associated node
     354              :                                 size_t nodeId;
     355              : 
     356              :                         //  scv part
     357              :                                 MathVector<dim> vLocalIP[nip]; // local integration point
     358              :                                 MathVector<worldDim> vGlobalIP[nip]; // global intergration point
     359              :                                 const number* vWeight; // weight at ip
     360              : 
     361              :                         //      local and global positions of this element
     362              :                                 MathVector<dim> vLocPos[numCo]; // local position of node
     363              :                                 MathVector<worldDim> vGloPos[numCo]; // global position of node
     364              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scv
     365              : 
     366              :                         // shapes and derivatives
     367              :                                 number vvShape[nip][nsh]; // shapes at ip
     368              :                                 MathVector<dim> vvLocalGrad[nip][nsh]; // local grad at ip
     369              :                                 MathVector<worldDim> vvGlobalGrad[nip][nsh]; // global grad at ip
     370              :                                 MathMatrix<worldDim,dim> vJtInv[nip]; // Jacobian transposed at ip
     371              :                                 number vDetJ[nip]; // Jacobian det at ip
     372              :                                 number vDetJMap[nip]; // Jacobian det at ip for scv integral map
     373              :                 };
     374              : 
     375              :         ///     boundary face
     376              :                 class BF
     377              :                 {
     378              :                         public:
     379              :                         /// number of integration points
     380              :                                 static const size_t nip = scvf_quad_rule_type::nip;
     381              : 
     382              :                         /// Number of corners of bf
     383              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     384              : 
     385              :                         public:
     386            0 :                                 BF() {}
     387              : 
     388              :                         /// index of SubControlVolume of the bf
     389            0 :                                 inline size_t node_id() const {return nodeId;}
     390              : 
     391              :                         /// outer normal on bf. Norm is equal to area
     392            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;} // includes area
     393              : 
     394              :                         /// volume of bf
     395            0 :                                 inline number volume() const {return Vol;}
     396              : 
     397              :                         /// number of integration points on scvf
     398            0 :                                 inline size_t num_ip() const {return nip;}
     399              : 
     400              :                         ///     integration weight
     401            0 :                                 inline number weight(size_t ip) const
     402            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip];}
     403              : 
     404              :                         /// local integration point of scvf
     405            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     406            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     407              : 
     408              :                         /// global integration point of scvf
     409            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     410            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     411              : 
     412              :                         /// Transposed Inverse of Jacobian in integration point
     413            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     414            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vJtInv[ip];}
     415              : 
     416              :                         /// Determinant of Jacobian in integration point
     417            0 :                                 inline number detJ(size_t ip) const
     418            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip];}
     419              : 
     420              :                         /// number of shape functions
     421            0 :                                 inline size_t num_sh() const {return nsh;}
     422              : 
     423              :                         /// value of shape function i in integration point
     424            0 :                                 inline number shape(size_t ip, size_t sh) const
     425            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip][sh];}
     426              : 
     427              :                         /// vector of shape functions in ip point
     428            0 :                                 inline const number* shape_vector(size_t ip) const
     429            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip];}
     430              : 
     431              :                         /// value of local gradient of shape function i in integration point
     432            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     433              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     434            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip][sh];}
     435              : 
     436              :                         /// vector of local gradients in ip point
     437            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     438            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip];}
     439              : 
     440              :                         /// value of global gradient of shape function i in integration point
     441            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     442              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     443            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip][sh];}
     444              : 
     445              :                         /// vector of global gradients in ip point
     446            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     447            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip];}
     448              : 
     449              :                         /// number of corners, that bound the scvf
     450            0 :                                 inline size_t num_corners() const {return numCo;}
     451              : 
     452              :                         /// return local corner number i
     453            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     454            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     455              : 
     456              :                         /// return glbal corner number i
     457            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     458            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     459              : 
     460              :                         private:
     461              :                         /// let outer class access private members
     462              :                                 friend class FVGeometry<TOrder, TElem, TWorldDim, TQuadOrder>;
     463              : 
     464              :                         //      id of scv this bf belongs to
     465              :                                 size_t nodeId;
     466              : 
     467              :                         // ordering is:
     468              :                         // 1D: edgeMidPoint
     469              :                         // 2D: edgeMidPoint, CenterOfElement
     470              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     471              :                                 MathVector<dim> vLocPos[numCo]; // local corners of bf
     472              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of bf
     473              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the bf
     474              : 
     475              :                         //      scvf part
     476              :                                 MathVector<dim> vLocalIP[nip]; // local integration point
     477              :                                 MathVector<worldDim> vGlobalIP[nip]; // global integration point
     478              :                                 const number* vWeight; // weight at ip
     479              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     480              :                                 number Vol; // volume of bf
     481              : 
     482              :                         //      shapes and derivatives
     483              :                                 number vvShape[nip][nsh]; // shapes at ip
     484              :                                 MathVector<dim> vvLocalGrad[nip][nsh]; // local grad at ip
     485              :                                 MathVector<worldDim> vvGlobalGrad[nip][nsh]; // global grad at ip
     486              :                                 MathMatrix<worldDim,dim> vJtInv[nip]; // Jacobian transposed at ip
     487              :                                 number vDetJ[nip]; // Jacobian det at ip
     488              :                 };
     489              : 
     490              : 
     491              :         public:
     492              :         /// construct object and initialize local values and sizes
     493              :                 FVGeometry();
     494              : 
     495              :         ///     update local data
     496              :                 void update_local_data();
     497              : 
     498              :         /// update Geometry for roid
     499              :                 void update_local(ReferenceObjectID roid,
     500              :                                   const LFEID& lfeID = LFEID(LFEID::LAGRANGE, worldDim, 1),
     501              :                                   size_t orderQuad = TQuadOrder);
     502              : 
     503              :         /// update data for given element
     504              :                 void update(GridObject* elem, const MathVector<worldDim>* vCornerCoords,
     505              :                             const ISubsetHandler* ish = NULL);
     506              : 
     507              :         /// update boundary data for given element
     508              :                 void update_boundary_faces(GridObject* elem,
     509              :                                            const MathVector<worldDim>* vCornerCoords,
     510              :                                            const ISubsetHandler* ish = NULL);
     511              : 
     512              :         /// number of SubControlVolumeFaces
     513            0 :                 inline size_t num_scvf() const {return numSCVF;};
     514              : 
     515              :         /// const access to SubControlVolumeFace number i
     516            0 :                 inline const SCVF& scvf(size_t i) const
     517            0 :                         {UG_ASSERT(i < num_scvf(), "Invalid Index."); return m_vSCVF[i];}
     518              : 
     519              :         /// number of SubControlVolumes
     520            0 :                 inline size_t num_scv() const {return numSCV;}
     521              : 
     522              :         /// const access to SubControlVolume number i
     523            0 :                 inline const SCV& scv(size_t i) const
     524            0 :                         {UG_ASSERT(i < num_scv(), "Invalid Index."); return m_vSCV[i];}
     525              : 
     526              :         /// number of shape functions
     527            0 :                 inline size_t num_sh() const {return nsh;}
     528              : 
     529              :         public:
     530              :         /// returns number of all scvf ips
     531            0 :                 size_t num_scvf_ips() const {return numSCVFIP;}
     532              : 
     533              :         /// returns all ips of scvf as they appear in scv loop
     534            0 :                 const MathVector<dim>* scvf_local_ips() const {return m_vLocSCVF_IP;}
     535              : 
     536              :         /// returns all ips of scvf as they appear in scv loop
     537            0 :                 const MathVector<worldDim>* scvf_global_ips() const {return m_vGlobSCVF_IP;}
     538              : 
     539              :         /// returns number of all scv ips
     540            0 :                 size_t num_scv_ips() const {return numSCVIP;}
     541              : 
     542              :         /// returns all ips of scv as they appear in scv loop
     543            0 :                 const MathVector<dim>* scv_local_ips() const {return m_vLocSCV_IP;}
     544              : 
     545              :         /// returns all ips of scv as they appear in scv loop
     546            0 :                 const MathVector<worldDim>* scv_global_ips() const {return m_vGlobSCV_IP;}
     547              : 
     548              : 
     549              :         protected:
     550              :         //      global and local ips on SCVF
     551              :                 MathVector<worldDim> m_vGlobSCVF_IP[numSCVFIP];
     552              :                 MathVector<dim> m_vLocSCVF_IP[numSCVFIP];
     553              : 
     554              :         //      global and local ips on SCVF
     555              :                 MathVector<worldDim> m_vGlobSCV_IP[numSCVIP];
     556              :                 MathVector<dim> m_vLocSCV_IP[numSCVIP];
     557              : 
     558              :         protected:
     559              :         //      maximum number of geom objects in a dimension
     560              :                 static const int maxMid = numSCVF + 1;
     561              : 
     562              :         //      subelement
     563            0 :                 struct SubElement
     564              :                 {
     565              :                 //      shape number of corners of subelement
     566              :                         size_t vDoFID[ref_elem_type::numCorners];
     567              : 
     568              :                 //      local and global geom object midpoints for each dimension
     569              :                 //      (most objects in 1 dim, i.e. number of edges, but +1 for 1D)
     570              :                         MathVector<dim> vvLocMid[dim+1][maxMid];
     571              :                         MathVector<worldDim> vvGloMid[dim+1][maxMid];
     572              : 
     573              :                 //      flag is subelement has boundary sides
     574              :                         bool isBndElem;
     575              : 
     576              :                 //      -1 is no bnd side, >= 0 corresponding side of whole element
     577              :                         std::vector<int> vElemBndSide;
     578              :                 };
     579              : 
     580              :         ///     subelements
     581              :                 SubElement m_vSubElem[numSubElem];
     582              : 
     583              :         public:
     584              :         /// add subset that is interpreted as boundary subset.
     585            0 :                 inline void add_boundary_subset(int subsetIndex) {m_mapVectorBF[subsetIndex];}
     586              : 
     587              :         /// removes subset that is interpreted as boundary subset.
     588            0 :                 inline void remove_boundary_subset(int subsetIndex) {m_mapVectorBF.erase(subsetIndex);}
     589              : 
     590              :         /// reset all boundary subsets
     591            0 :                 inline void clear_boundary_subsets() {m_mapVectorBF.clear();}
     592              : 
     593              :         /// number of registered boundary subsets
     594            0 :                 inline size_t num_boundary_subsets() {return m_mapVectorBF.size();}
     595              : 
     596              :         /// number of all boundary faces
     597            0 :                 inline size_t num_bf() const
     598              :                 {
     599              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     600              :                         size_t num = 0;
     601            0 :                         for ( it=m_mapVectorBF.begin() ; it != m_mapVectorBF.end(); it++ )
     602            0 :                                 num += (*it).second.size();
     603            0 :                         return num;
     604              :                 }
     605              : 
     606              :         /// number of boundary faces on subset 'subsetIndex'
     607            0 :                 inline size_t num_bf(int si) const
     608              :                 {
     609              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     610              :                         it = m_mapVectorBF.find(si);
     611            0 :                         if(it == m_mapVectorBF.end()) return 0;
     612            0 :                         else return (*it).second.size();
     613              :                 }
     614              : 
     615              :         /// returns the boundary face i for subsetIndex
     616            0 :                 inline const BF& bf(int si, size_t i) const
     617              :                 {
     618              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     619              :                         it = m_mapVectorBF.find(si);
     620            0 :                         if(it == m_mapVectorBF.end()) UG_THROW("FVGeom: No BndSubset"<<si);
     621            0 :                         return (*it).second[i];
     622              :                 }
     623              : 
     624              :         /// returns reference to vector of boundary faces for subsetIndex
     625            0 :                 inline const std::vector<BF>& bf(int si) const
     626              :                 {
     627              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     628              :                         it = m_mapVectorBF.find(si);
     629            0 :                         if(it == m_mapVectorBF.end()) return m_vEmptyVectorBF;
     630            0 :                         return (*it).second;
     631              :                 }
     632              : 
     633            0 :                 void reset_curr_elem() {m_pElem = NULL;}
     634              : 
     635              :         protected:
     636              :                 std::map<int, std::vector<BF> > m_mapVectorBF;
     637              :                 std::vector<BF> m_vEmptyVectorBF;
     638              : 
     639              :         private:
     640              :         ///     pointer to current element
     641              :                 TElem* m_pElem;
     642              : 
     643              :         ///     corners of reference element
     644              :                 MathVector<dim> m_vLocCorner[ref_elem_type::numCorners];
     645              : 
     646              :         ///     SubControlVolumeFaces
     647              :                 SCVF m_vSCVF[numSCVF];
     648              : 
     649              :         ///     SubControlVolumes
     650              :                 SCV m_vSCV[numSCV];
     651              : 
     652              :         ///     Reference Mapping
     653              :                 ReferenceMapping<ref_elem_type, worldDim> m_rMapping;
     654              : 
     655              :         ///     Reference Element
     656              :                 const ref_elem_type& m_rRefElem;
     657              : 
     658              :         ///     Shape function set
     659              :                 const local_shape_fct_set_type& m_rTrialSpace;
     660              : 
     661              :         ///     Quad Rule scvf
     662              :                 const scvf_quad_rule_type& m_rSCVFQuadRule;
     663              : 
     664              :         ///     Quad Rule scv
     665              :                 const scv_quad_rule_type& m_rSCVQuadRule;
     666              : };
     667              : 
     668              : ////////////////////////////////////////////////////////////////////////////////
     669              : // Dimension FV Geometry (all orders)   DIM FV
     670              : ////////////////////////////////////////////////////////////////////////////////
     671              : 
     672              : /// Geometry and shape functions for any order Vertex-Centered Finite Volume
     673              : /**
     674              :  * \tparam      TDim            reference element dim
     675              :  * \tparam      TWorldDim       (physical) world dimension
     676              :  */
     677              : template <int TWorldDim, int TDim = TWorldDim>
     678              : class DimFVGeometry : public FVGeometryBase
     679              : {
     680              :         public:
     681              :         ///     traits used
     682              :                 typedef fv1_dim_traits<TDim, TWorldDim> traits;
     683              : 
     684              :         ///     dimension of reference element
     685              :                 static const int dim = TDim;
     686              : 
     687              :         ///     dimension of world
     688              :                 static const int worldDim = TWorldDim;
     689              : 
     690              :         public:
     691              :         ///     type of SubControlVolumeFace
     692              :                 typedef typename traits::scvf_type scvf_type;
     693              : 
     694              :         ///     type of SubControlVolume
     695              :                 typedef typename traits::scv_type scv_type;
     696              : 
     697              :         ///     Hanging node flag: this Geometry does not support hanging nodes
     698              :                 static const bool usesHangingNodes = false;
     699              : 
     700              :         /// flag indicating if local data may change
     701              :                 static const bool staticLocalData = false;
     702              : 
     703              :         public:
     704              :         ///     Sub-Control Volume Face structure
     705              :                 class SCVF
     706              :                 {
     707              :                         public:
     708              :                         ///     Number of corners of scvf
     709              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     710              : 
     711              :                         public:
     712            0 :                                 SCVF() {}
     713              : 
     714              :                         /// index of SubControlVolume on one side of the scvf
     715            0 :                                 inline size_t from() const {return From;}
     716              : 
     717              :                         /// index of SubControlVolume on one side of the scvf
     718            0 :                                 inline size_t to() const {return To;}
     719              : 
     720              :                         /// number of integration points on scvf
     721            0 :                                 inline size_t num_ip() const {return nip;}
     722              : 
     723              :                         ///     integration weight
     724            0 :                                 inline number weight(size_t ip) const
     725            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip]*vDetJMap[ip];}
     726              : 
     727              :                         /// local integration point of scvf
     728            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     729            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     730              : 
     731              :                         /// global integration point of scvf
     732            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     733            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     734              : 
     735              :                         /// normal on scvf (points direction "from"->"to"), normalized
     736            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;}
     737              : 
     738              :                         /// Transposed Inverse of Jacobian in integration point
     739            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     740            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vJtInv[ip];}
     741              : 
     742              :                         /// Determinant of Jacobian in integration point
     743            0 :                                 inline number detJ(size_t ip) const
     744            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip];}
     745              : 
     746              :                         /// number of shape functions
     747            0 :                                 inline size_t num_sh() const {return nsh;}
     748              : 
     749              :                         /// value of shape function i in integration point
     750            0 :                                 inline number shape(size_t ip, size_t sh) const
     751            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip][sh];}
     752              : 
     753              :                         /// vector of shape functions in ip point
     754            0 :                                 inline const number* shape_vector(size_t ip) const
     755            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvShape[ip][0];}
     756              : 
     757              :                         /// value of local gradient of shape function i in integration point
     758            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     759              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     760            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip][sh];}
     761              : 
     762              :                         /// vector of local gradients in ip point
     763            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     764            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvLocalGrad[ip][0];}
     765              : 
     766              :                         /// value of global gradient of shape function i in integration point
     767            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     768              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     769            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip][sh];}
     770              : 
     771              :                         /// vector of gloabl gradients in ip point
     772            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     773            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvGlobalGrad[ip][0];}
     774              : 
     775              :                         /// number of corners, that bound the scvf
     776            0 :                                 inline size_t num_corners() const {return numCo;}
     777              : 
     778              :                         /// return local corner number i
     779            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     780            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     781              : 
     782              :                         /// return glbal corner number i
     783            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     784            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     785              : 
     786              :                         private:
     787              :                         //      let outer class access private members
     788              :                                 friend class DimFVGeometry<worldDim, dim>;
     789              : 
     790              :                         // This scvf separates the scv with the ids given in "from" and "to"
     791              :                         // The computed normal points in direction from->to
     792              :                                 size_t From, To;
     793              : 
     794              :                         //      The normal on the SCVF pointing (from -> to)
     795              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     796              : 
     797              :                         // ordering is:
     798              :                         // 1D: edgeMidPoint
     799              :                         // 2D: edgeMidPoint, CenterOfElement
     800              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
     801              :                                 MathVector<dim> vLocPos[numCo]; // local corners of scvf
     802              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of scvf
     803              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scvf
     804              : 
     805              :                         // scvf part
     806              :                                 size_t nip;
     807              :                                 std::vector<MathVector<dim> > vLocalIP; // local integration point (size: nip)
     808              :                                 std::vector<MathVector<worldDim> > vGlobalIP; // global integration point (size: nip)
     809              :                                 const number* vWeight; // weight at ip
     810              : 
     811              :                         // shapes and derivatives
     812              :                                 size_t nsh;
     813              :                                 std::vector<std::vector<number> > vvShape; // shapes at ip (size: nip x nsh)
     814              :                                 std::vector<std::vector<MathVector<dim> > > vvLocalGrad; // local grad at ip (size: nip x nsh)
     815              :                                 std::vector<std::vector<MathVector<worldDim> > > vvGlobalGrad; // global grad at ip (size: nip x nsh)
     816              :                                 std::vector<MathMatrix<worldDim,dim> > vJtInv; // Jacobian transposed at ip (size: nip)
     817              :                                 std::vector<number> vDetJ; // Jacobian det at ip (size: nip)
     818              :                                 std::vector<number> vDetJMap; // Jacobian det at ip (size: nip)
     819              :                 };
     820              : 
     821              :         ///     sub control volume structure
     822              :                 class SCV
     823              :                 {
     824              :                         public:
     825              :                         /// Number of corners of scvf
     826              :                                 static const size_t numCo =     traits::NumCornersOfSCV;
     827              : 
     828              :                         public:
     829            0 :                                 SCV() {};
     830              : 
     831              :                         /// number of corners, that bound the scvf
     832            0 :                                 inline size_t num_corners() const {return numCo;}
     833              : 
     834              :                         /// return local corner number i
     835            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
     836            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
     837              : 
     838              :                         /// return glbal corner number i
     839            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
     840            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
     841              : 
     842              :                         /// node id that this scv is associated to
     843            0 :                                 inline size_t node_id() const {return nodeId;}
     844              : 
     845              :                         /// number of integration points
     846            0 :                                 inline size_t num_ip() const {return nip;}
     847              : 
     848              :                         ///     weigth of integration point
     849            0 :                                 inline number weight(size_t ip) const
     850            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip]*vDetJMap[ip];}
     851              : 
     852              :                         /// local integration point of scv
     853            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     854            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     855              : 
     856              :                         /// global integration point
     857            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     858            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     859              : 
     860              :                         /// Transposed Inverse of Jacobian in integration point
     861            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     862            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vJtInv[ip];}
     863              : 
     864              :                         /// Determinant of Jacobian in integration point
     865            0 :                                 inline number detJ(size_t ip) const
     866            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vDetJ[ip];}
     867              : 
     868              :                         /// number of shape functions
     869            0 :                                 inline size_t num_sh() const {return nsh;}
     870              : 
     871              :                         /// value of shape function i in integration point
     872            0 :                                 inline number shape(size_t ip, size_t sh) const
     873            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return vvShape[ip][sh];}
     874              : 
     875              :                         /// vector of shape functions in ip point
     876            0 :                                 inline const number* shape_vector(size_t ip) const
     877            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return &vvShape[ip][0];}
     878              : 
     879              :                         /// value of local gradient of shape function i in integration point
     880            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     881              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     882            0 :                                          UG_ASSERT(ip<num_ip(),"Wring index."); return vvLocalGrad[ip][sh];}
     883              : 
     884              :                         /// vector of local gradients in ip point
     885            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     886            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return &vvLocalGrad[ip][0];}
     887              : 
     888              :                         /// value of global gradient of shape function i in integration point
     889            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     890              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     891            0 :                                          UG_ASSERT(ip<num_ip(),"Wring index."); return vvGlobalGrad[ip][sh];}
     892              : 
     893              :                         /// vector of global gradients in ip point
     894            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     895            0 :                                         {UG_ASSERT(ip<num_ip(),"Wring index."); return &vvGlobalGrad[ip][0];}
     896              : 
     897              :                         private:
     898              :                         //      let outer class access private members
     899              :                                 friend class DimFVGeometry<worldDim, dim>;
     900              : 
     901              :                         //  node id of associated node
     902              :                                 size_t nodeId;
     903              : 
     904              :                         //      local and global positions of this element
     905              :                                 MathVector<dim> vLocPos[numCo]; // local position of node
     906              :                                 MathVector<worldDim> vGloPos[numCo]; // global position of node
     907              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the scv
     908              : 
     909              :                         //  scv part
     910              :                                 size_t nip;
     911              :                                 std::vector<MathVector<dim> > vLocalIP; // local integration point (size: nip)
     912              :                                 std::vector<MathVector<worldDim> > vGlobalIP; // global intergration point (size: nip)
     913              :                                 const number* vWeight; // weight at ip
     914              : 
     915              :                         // shapes and derivatives
     916              :                                 size_t nsh;
     917              :                                 std::vector<std::vector<number> > vvShape; // shapes at ip (size: nip x nsh)
     918              :                                 std::vector<std::vector<MathVector<dim> > > vvLocalGrad; // local grad at ip (size: nip x nsh)
     919              :                                 std::vector<std::vector<MathVector<worldDim> > > vvGlobalGrad; // global grad at ip (size: nip x nsh)
     920              :                                 std::vector<MathMatrix<worldDim,dim> > vJtInv; // Jacobian transposed at ip (size: nip)
     921              :                                 std::vector<number> vDetJ; // Jacobian det at ip (size: nip)
     922              :                                 std::vector<number> vDetJMap; // Jacobian det at ip (size: nip)
     923              :                 };
     924              : 
     925              :         ///     boundary face
     926              :                 class BF
     927              :                 {
     928              :                         public:
     929              :                         /// Number of corners of bf
     930              :                                 static const size_t numCo = traits::NumCornersOfSCVF;
     931              : 
     932              :                         public:
     933            0 :                                 BF() {}
     934              : 
     935              :                         /// index of SubControlVolume of the bf
     936            0 :                                 inline size_t node_id() const {return nodeId;}
     937              : 
     938              :                         /// outer normal on bf. Norm is equal to area
     939            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;} // includes area
     940              : 
     941              :                         /// volume of bf
     942            0 :                                 inline number volume() const {return Vol;}
     943              : 
     944              :                         /// number of integration points on scvf
     945            0 :                                 inline size_t num_ip() const {return nip;}
     946              : 
     947              :                         ///     integration weight
     948            0 :                                 inline number weight(size_t ip) const
     949            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vWeight[ip];}
     950              : 
     951              :                         /// local integration point of scvf
     952            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     953            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     954              : 
     955              :                         /// global integration point of scvf
     956            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     957            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     958              : 
     959              :                         /// Transposed Inverse of Jacobian in integration point
     960            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     961            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vJtInv[ip];}
     962              : 
     963              :                         /// Determinant of Jacobian in integration point
     964            0 :                                 inline number detJ(size_t ip) const
     965            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip];}
     966              : 
     967              :                         /// number of shape functions
     968            0 :                                 inline size_t num_sh() const {return nsh;}
     969              : 
     970              :                         /// value of shape function i in integration point
     971            0 :                                 inline number shape(size_t ip, size_t sh) const
     972            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip][sh];}
     973              : 
     974              :                         /// vector of shape functions in ip point
     975            0 :                                 inline const number* shape_vector(size_t ip) const
     976            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvShape[ip][0];}
     977              : 
     978              :                         /// value of local gradient of shape function i in integration point
     979            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     980              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     981            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip][sh];}
     982              : 
     983              :                         /// vector of local gradients in ip point
     984            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     985            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvLocalGrad[ip][0];}
     986              : 
     987              :                         /// value of global gradient of shape function i in integration point
     988            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     989              :                                         {UG_ASSERT(sh < num_sh(), "Invalid index");
     990            0 :                                          UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip][sh];}
     991              : 
     992              :                         /// vector of global gradients in ip point
     993            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     994            0 :                                         {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvGlobalGrad[ip][0];}
     995              : 
     996              :                         /// number of corners, that bound the scvf
     997            0 :                                 inline size_t num_corners() const {return numCo;}
     998              : 
     999              :                         /// return local corner number i
    1000            0 :                                 inline const MathVector<dim>& local_corner(size_t co) const
    1001            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vLocPos[co];}
    1002              : 
    1003              :                         /// return glbal corner number i
    1004            0 :                                 inline const MathVector<worldDim>& global_corner(size_t co) const
    1005            0 :                                         {UG_ASSERT(co < num_corners(), "Invalid index."); return vGloPos[co];}
    1006              : 
    1007              :                         private:
    1008              :                         /// let outer class access private members
    1009              :                                 friend class DimFVGeometry<worldDim, dim>;
    1010              : 
    1011              :                         //      id of scv this bf belongs to
    1012              :                                 size_t nodeId;
    1013              : 
    1014              :                         // ordering is:
    1015              :                         // 1D: edgeMidPoint
    1016              :                         // 2D: edgeMidPoint, CenterOfElement
    1017              :                         // 3D: edgeMidPoint, Side one, CenterOfElement, Side two
    1018              :                                 MathVector<dim> vLocPos[numCo]; // local corners of bf
    1019              :                                 MathVector<worldDim> vGloPos[numCo]; // global corners of bf
    1020              :                                 MidID vMidID[numCo]; // dimension and id of object, that's midpoint bounds the bf
    1021              : 
    1022              :                         //      scvf part
    1023              :                                 size_t nip;
    1024              :                                 std::vector<MathVector<dim> > vLocalIP; // local integration point (size: nip)
    1025              :                                 std::vector<MathVector<worldDim> > vGlobalIP; // global integration point (size: nip)
    1026              :                                 const number* vWeight; // weight at ip
    1027              :                                 MathVector<worldDim> Normal; // normal (incl. area)
    1028              :                                 number Vol; // volume of bf
    1029              : 
    1030              :                         //      shapes and derivatives
    1031              :                                 size_t nsh;
    1032              :                                 std::vector<std::vector<number> > vvShape; // shapes at ip (size: nip x nsh)
    1033              :                                 std::vector<std::vector<MathVector<dim> > > vvLocalGrad; // local grad at ip (size: nip x nsh)
    1034              :                                 std::vector<std::vector<MathVector<worldDim> > > vvGlobalGrad; // global grad at ip (size: nip x nsh)
    1035              :                                 std::vector<MathMatrix<worldDim,dim> > vJtInv; // Jacobian transposed at ip (size: nip)
    1036              :                                 std::vector<number> vDetJ; // Jacobian det at ip (size: nip)
    1037              :                 };
    1038              : 
    1039              : 
    1040              :         public:
    1041              :         /// construct object and initialize local values and sizes
    1042              :                 DimFVGeometry();
    1043              : 
    1044              :         ///     update local data
    1045              :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID, size_t orderQuad);
    1046            0 :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID)
    1047              :                 {
    1048            0 :                         update_local(roid, lfeID, lfeID.order() + 1);
    1049            0 :                 }
    1050              : 
    1051              :         /// update data for given element
    1052            0 :                 void update(GridObject* pElem, const MathVector<worldDim>* vCornerCoords,
    1053              :                             const ISubsetHandler* ish = NULL)
    1054              :                 {
    1055            0 :                         update(pElem, vCornerCoords, m_lfeID, m_quadOrderSCV, ish);
    1056            0 :                 }
    1057              : 
    1058              :         /// update data for given element
    1059              :                 void update(GridObject* pElem, const MathVector<worldDim>* vCornerCoords,
    1060              :                             const LFEID& lfeID, size_t orderQuad,
    1061              :                             const ISubsetHandler* ish = NULL);
    1062              : 
    1063              :         /// update boundary data for given element
    1064              :                 void update_boundary_faces(GridObject* pElem,
    1065              :                                            const MathVector<worldDim>* vCornerCoords,
    1066              :                                            const ISubsetHandler* ish = NULL);
    1067              : 
    1068              :         /// number of SubControlVolumeFaces
    1069            0 :                 inline size_t num_scvf() const {return m_numSCVF;};
    1070              : 
    1071              :         /// const access to SubControlVolumeFace number i
    1072            0 :                 inline const SCVF& scvf(size_t i) const
    1073            0 :                         {UG_ASSERT(i < num_scvf(), "Invalid Index."); return m_vSCVF[i];}
    1074              : 
    1075              :         /// number of SubControlVolumes
    1076            0 :                 inline size_t num_scv() const {return m_numSCV;}
    1077              : 
    1078              :         /// const access to SubControlVolume number i
    1079            0 :                 inline const SCV& scv(size_t i) const
    1080            0 :                         {UG_ASSERT(i < num_scv(), "Invalid Index."); return m_vSCV[i];}
    1081              : 
    1082              :         /// number of shape functions
    1083            0 :                 inline size_t num_sh() const {return m_nsh;};
    1084              : 
    1085              :         public:
    1086              :         /// returns number of all scvf ips
    1087            0 :                 size_t num_scvf_ips() const {return m_numSCVFIP;}
    1088              : 
    1089              :         /// returns all ips of scvf as they appear in scv loop
    1090            0 :                 const MathVector<dim>* scvf_local_ips() const {return &(m_vLocSCVF_IP[0]);}
    1091              : 
    1092              :         /// returns all ips of scvf as they appear in scv loop
    1093            0 :                 const MathVector<worldDim>* scvf_global_ips() const {return &(m_vGlobSCVF_IP[0]);}
    1094              : 
    1095              :         /// returns number of all scv ips
    1096            0 :                 size_t num_scv_ips() const {return m_numSCVIP;}
    1097              : 
    1098              :         /// returns all ips of scv as they appear in scv loop
    1099            0 :                 const MathVector<dim>* scv_local_ips() const {return &(m_vLocSCV_IP[0]);}
    1100              : 
    1101              :         /// returns all ips of scv as they appear in scv loop
    1102            0 :                 const MathVector<worldDim>* scv_global_ips() const {return &(m_vGlobSCV_IP[0]);}
    1103              : 
    1104              : 
    1105              :         protected:
    1106              :         //      global and local ips on SCVF (size: numSCVFIP)
    1107              :                 std::vector<MathVector<worldDim> > m_vGlobSCVF_IP;
    1108              :                 std::vector<MathVector<dim> > m_vLocSCVF_IP;
    1109              : 
    1110              :         //      global and local ips on SCVF
    1111              :                 std::vector<MathVector<worldDim> > m_vGlobSCV_IP;
    1112              :                 std::vector<MathVector<dim> > m_vLocSCV_IP;
    1113              : 
    1114              :         protected:
    1115              :         //      miximum number of geom objects in a dimension
    1116              :                 static const int maxMid = traits::maxNumSCVF +1;
    1117              : 
    1118              :         //      subelement
    1119            0 :                 struct SubElement
    1120              :                 {
    1121              :                 //      shape number of corners of subelement
    1122              :                         size_t vDoFID[traits::maxNumSCV];
    1123              : 
    1124              :                 //      local and global geom object midpoints for each dimension
    1125              :                 //      (most objects in 1 dim, i.e. number of edges, but +1 for 1D)
    1126              :                         MathVector<dim> vvLocMid[dim+1][maxMid];
    1127              :                         MathVector<worldDim> vvGloMid[dim+1][maxMid];
    1128              : 
    1129              :                 //      flag is subelement has boundary sides
    1130              :                         bool isBndElem;
    1131              : 
    1132              :                 //      -1 is no bnd side, >= 0 corresponding side of whole element
    1133              :                         std::vector<int> vElemBndSide;
    1134              :                 };
    1135              : 
    1136              :         ///     subelements (size: numSubElem)
    1137              :                 std::vector<SubElement> m_vSubElem;
    1138              : 
    1139              :         public:
    1140              :         /// add subset that is interpreted as boundary subset.
    1141            0 :                 inline void add_boundary_subset(int subsetIndex) {m_mapVectorBF[subsetIndex];}
    1142              : 
    1143              :         /// removes subset that is interpreted as boundary subset.
    1144            0 :                 inline void remove_boundary_subset(int subsetIndex) {m_mapVectorBF.erase(subsetIndex);}
    1145              : 
    1146              :         /// reset all boundary subsets
    1147            0 :                 inline void clear_boundary_subsets() {m_mapVectorBF.clear();}
    1148              : 
    1149              :         /// number of registered boundary subsets
    1150            0 :                 inline size_t num_boundary_subsets() {return m_mapVectorBF.size();}
    1151              : 
    1152              :         /// number of all boundary faces
    1153            0 :                 inline size_t num_bf() const
    1154              :                 {
    1155              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1156              :                         size_t num = 0;
    1157            0 :                         for ( it=m_mapVectorBF.begin() ; it != m_mapVectorBF.end(); it++ )
    1158            0 :                                 num += (*it).second.size();
    1159            0 :                         return num;
    1160              :                 }
    1161              : 
    1162              :         /// number of boundary faces on subset 'subsetIndex'
    1163            0 :                 inline size_t num_bf(int si) const
    1164              :                 {
    1165              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1166              :                         it = m_mapVectorBF.find(si);
    1167            0 :                         if(it == m_mapVectorBF.end()) return 0;
    1168            0 :                         else return (*it).second.size();
    1169              :                 }
    1170              : 
    1171              :         /// returns the boundary face i for subsetIndex
    1172            0 :                 inline const BF& bf(int si, size_t i) const
    1173              :                 {
    1174              :                         UG_ASSERT(i < num_bf(si), "Invalid index.");
    1175              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1176              :                         it = m_mapVectorBF.find(si);
    1177            0 :                         if(it == m_mapVectorBF.end()) UG_THROW("DimFVGeom: No BndSubset: "<<si);
    1178            0 :                         return (*it).second[i];
    1179              :                 }
    1180              : 
    1181              :         /// returns reference to vector of boundary faces for subsetIndex
    1182            0 :                 inline const std::vector<BF>& bf(int si) const
    1183              :                 {
    1184              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
    1185              :                         it = m_mapVectorBF.find(si);
    1186            0 :                         if(it == m_mapVectorBF.end()) return m_vEmptyVectorBF;
    1187            0 :                         return (*it).second;
    1188              :                 }
    1189              : 
    1190            0 :                 void reset_curr_elem() {m_pElem = NULL;}
    1191              : 
    1192              :         protected:
    1193              :                 std::map<int, std::vector<BF> > m_mapVectorBF;
    1194              :                 std::vector<BF> m_vEmptyVectorBF;
    1195              : 
    1196              :         private:
    1197              :         ///     pointer to current element
    1198              :                 GridObject* m_pElem;
    1199              : 
    1200              :         ///     current reference object id
    1201              :                 ReferenceObjectID m_roid;
    1202              : 
    1203              :         ///     current order
    1204              :                 int m_orderShape;
    1205              : 
    1206              :         ///     current trial space
    1207              :                 LFEID m_lfeID;
    1208              : 
    1209              :         ///     current number of subelements
    1210              :                 size_t m_numSubElem;
    1211              : 
    1212              :         ///     number of shape functions
    1213              :                 size_t m_nsh;
    1214              : 
    1215              :         ///     current number of scvf
    1216              :                 size_t m_numSCVF;
    1217              : 
    1218              :         ///     current number of SCVF per SubElement
    1219              :                 size_t m_numSCVFPerSubElem;
    1220              : 
    1221              :         ///     SubControlVolumeFaces (size: numSCVF)
    1222              :                 std::vector<SCVF> m_vSCVF;
    1223              : 
    1224              :         ///     quadrature order
    1225              :                 int m_quadOrderSCVF;
    1226              : 
    1227              :         ///     number of scvf ip
    1228              :                 size_t m_numSCVFIP;
    1229              : 
    1230              : 
    1231              :         ///     current number of scv
    1232              :                 size_t m_numSCV;
    1233              : 
    1234              :         ///     number of SCV per SubElement
    1235              :                 size_t m_numSCVPerSubElem;
    1236              : 
    1237              :         ///     SubControlVolumes (size: numSCV)
    1238              :                 std::vector<SCV> m_vSCV;
    1239              : 
    1240              :         ///     current quadrature order scv
    1241              :                 int m_quadOrderSCV;
    1242              : 
    1243              :         ///     number of scv ip
    1244              :                 size_t m_numSCVIP;
    1245              : };
    1246              : 
    1247              : }
    1248              : 
    1249              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_VOLUME_HIGHER_ORDER_GEOMETRY__ */
        

Generated by: LCOV version 2.0-1