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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_ELEMENT_GEOMETRY__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_ELEMENT_GEOMETRY__
      35              : 
      36              : #include "lib_grid/tools/subset_handler_interface.h"
      37              : #include "lib_disc/quadrature/quadrature.h"
      38              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      39              : #include "lib_disc/reference_element/reference_mapping_provider.h"
      40              : #include "lib_disc/reference_element/reference_mapping.h"
      41              : #include "common/util/provider.h"
      42              : 
      43              : #include <cmath>
      44              : 
      45              : namespace ug{
      46              : 
      47              : template <   typename TElem, int TWorldDim,
      48              :                         typename TTrialSpace, typename TQuadratureRule>
      49              : class FEGeometry
      50              : {
      51              :         public:
      52              :         ///     type of reference element
      53              :                 typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
      54              : 
      55              :         /// reference element dimension
      56              :                 static const int dim = ref_elem_type::dim;
      57              : 
      58              :         /// world dimension
      59              :                 static const int worldDim = TWorldDim;
      60              : 
      61              :         ///     type of trial space
      62              :                 typedef TTrialSpace trial_space_type;
      63              : 
      64              :         ///     type of quadrature rule
      65              :                 typedef TQuadratureRule quad_rule_type;
      66              : 
      67              :         ///     number of shape functions
      68              :                 static const size_t nsh = trial_space_type::nsh;
      69              : 
      70              :         ///     number of integration points
      71              :                 static const size_t nip = quad_rule_type::nip;
      72              : 
      73              :         /// flag indicating if local data may change
      74              :                 static const bool staticLocalData = true;
      75              : 
      76              :         public:
      77              :         ///     Constructor
      78              :                 FEGeometry();
      79              : 
      80              :         /// number of integration points
      81              :                 size_t num_ip() const {return nip;}
      82              : 
      83              :         /// number of shape functions
      84              :                 size_t num_sh() const {return nsh;}
      85              : 
      86              :         /// weight for integration point
      87            0 :                 number weight(size_t ip) const {return m_vDetJ[ip] * m_rQuadRule.weight(ip);}
      88              : 
      89              :         /// local integration point
      90              :                 const MathVector<dim>& local_ip(size_t ip) const {return m_rQuadRule.point(ip);}
      91              : 
      92              :         /// global integration point
      93              :                 const MathVector<worldDim>& global_ip(size_t ip) const
      94              :                 {
      95              :                         UG_ASSERT(ip < nip, "Wrong ip.");
      96              :                         return m_vIPGlobal[ip];
      97              :                 }
      98              : 
      99              :         /// local integration point
     100              :                 const MathVector<dim>* local_ips() const {return m_rQuadRule.points();}
     101              : 
     102              :         /// global integration point
     103            0 :                 const MathVector<worldDim>* global_ips() const{return &m_vIPGlobal[0];}
     104              : 
     105              :                 /// shape function at ip
     106              :                 number shape(size_t ip, size_t sh) const
     107              :                 {
     108              :                         UG_ASSERT(ip < nip, "Wrong index"); UG_ASSERT(sh < nsh, "Wrong index");
     109            0 :                         return m_vvShape[ip][sh];
     110              :                 }
     111              : 
     112              :         /// local gradient at ip
     113              :                 const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     114              :                 {
     115              :                         UG_ASSERT(ip < nip, "Wrong index"); UG_ASSERT(sh < nsh, "Wrong index");
     116              :                         return m_vvGradLocal[ip][sh];
     117              :                 }
     118              : 
     119              :         /// global gradient at ip
     120              :                 const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     121              :                 {
     122              :                         UG_ASSERT(ip < nip, "Wrong index"); UG_ASSERT(sh < nsh, "Wrong index");
     123              :                         return m_vvGradGlobal[ip][sh];
     124              :                 }
     125              : 
     126              :         public:
     127              :         /// update Geometry for roid
     128              :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID, size_t orderQuad);
     129              :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID){
     130              :                         update_local(roid, lfeID, 2*lfeID.order() + 1);
     131              :                 }
     132              : 
     133              :         /// update Geometry for corners
     134              :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner)
     135              :                 {
     136            0 :                         update(pElem, vCorner, LFEID(), m_rQuadRule.order());
     137              :                 }
     138              : 
     139              :         /// update Geometry for corners
     140              :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner,
     141              :                             const LFEID& lfeID, size_t orderQuad);
     142              :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner,
     143              :                             const LFEID& lfeID){
     144              :                         update(pElem, vCorner, lfeID, 2*lfeID.order() + 1);
     145              :                 }
     146              : 
     147              :         protected:
     148              :         ///     current element
     149              :                 TElem* m_pElem;
     150              : 
     151              :         ///     Quadrature rule
     152              :                 const quad_rule_type& m_rQuadRule;
     153              : 
     154              :         ///     Quadrature rule
     155              :                 const trial_space_type& m_rTrialSpace;
     156              : 
     157              :         ///     reference mapping
     158              :                 ReferenceMapping<ref_elem_type, worldDim> m_mapping;
     159              : 
     160              :         ///     global integration points
     161              :                 MathVector<worldDim> m_vIPGlobal[nip];
     162              : 
     163              :         ///     shape functions evaluated at ip
     164              :                 number m_vvShape[nip][nsh];
     165              : 
     166              :         ///     global gradient evaluated at ip
     167              :                 MathVector<dim> m_vvGradLocal[nip][nsh];
     168              : 
     169              :         ///     local gradient evaluated at ip
     170              :                 MathVector<worldDim> m_vvGradGlobal[nip][nsh];
     171              : 
     172              :         ///     jacobian of transformation at ip
     173              :                 MathMatrix<worldDim,dim> m_vJTInv[nip];
     174              : 
     175              :         ///     determinate of transformation at ip
     176              :                 number m_vDetJ[nip];
     177              : };
     178              : 
     179              : 
     180              : 
     181              : template <int TWorldDim, int TRefDim = TWorldDim>
     182              : class DimFEGeometry
     183              : {
     184              :         public:
     185              :         /// reference element dimension
     186              :                 static const int dim = TRefDim;
     187              : 
     188              :         /// world dimension
     189              :                 static const int worldDim = TWorldDim;
     190              : 
     191              :         /// flag indicating if local data may change
     192              :                 static const bool staticLocalData = false;
     193              : 
     194              :         public:
     195              :         ///     default Constructor
     196              :                 DimFEGeometry();
     197              : 
     198              :         ///     Constructor
     199              :                 DimFEGeometry(size_t order, LFEID lfeid);
     200              : 
     201              :         ///     Constructor
     202              :                 DimFEGeometry(ReferenceObjectID roid, size_t order, LFEID lfeid);
     203              : 
     204              :         /// number of integration points
     205            0 :                 size_t num_ip() const {return m_nip;}
     206              : 
     207              :         /// number of shape functions
     208            0 :                 size_t num_sh() const {return m_nsh;}
     209              : 
     210              :         /// weight for integration point
     211            0 :                 number weight(size_t ip) const
     212              :                 {
     213              :                         UG_ASSERT(ip < m_nip, "Wrong index");
     214            0 :                         return m_vDetJ[ip] * m_vQuadWeight[ip];
     215              :                 }
     216              : 
     217              :         /// local integration point
     218            0 :                 const MathVector<dim>& local_ip(size_t ip) const
     219              :                 {
     220              :                         UG_ASSERT(ip < m_nip, "Wrong index");
     221            0 :                         return m_vIPLocal[ip];
     222              :                 }
     223              : 
     224              :         /// global integration point
     225            0 :                 const MathVector<worldDim>& global_ip(size_t ip) const
     226              :                 {
     227              :                         UG_ASSERT(ip < m_vIPGlobal.size(), "Wrong ip.");
     228            0 :                         return m_vIPGlobal[ip];
     229              :                 }
     230              : 
     231              :         /// local integration point
     232            0 :                 const MathVector<dim>* local_ips() const {return m_vIPLocal;}
     233              : 
     234              :         /// global integration point
     235            0 :                 const MathVector<worldDim>* global_ips() const{return &m_vIPGlobal[0];}
     236              : 
     237              :         /// shape function at ip
     238            0 :                 number shape(size_t ip, size_t sh) const
     239              :                 {
     240              :                         UG_ASSERT(ip < m_vvShape.size(), "Wrong index");
     241              :                         UG_ASSERT(sh < m_vvShape[ip].size(), "Wrong index");
     242            0 :                         return m_vvShape[ip][sh];
     243              :                 }
     244              : 
     245              :         /// local gradient at ip
     246            0 :                 const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     247              :                 {
     248              :                         UG_ASSERT(ip < m_vvGradLocal.size(), "Wrong index");
     249              :                         UG_ASSERT(sh < m_vvGradLocal[ip].size(), "Wrong index");
     250            0 :                         return m_vvGradLocal[ip][sh];
     251              :                 }
     252              : 
     253              :         /// global gradient at ip
     254            0 :                 const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     255              :                 {
     256              :                         UG_ASSERT(ip < m_vvGradGlobal.size(), "Wrong index");
     257              :                         UG_ASSERT(sh < m_vvGradGlobal[ip].size(), "Wrong index");
     258            0 :                         return m_vvGradGlobal[ip][sh];
     259              :                 }
     260              : 
     261              :         /// update Geometry for roid
     262              :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID, size_t orderQuad);
     263            0 :                 void update_local(ReferenceObjectID roid, const LFEID& lfeID){
     264            0 :                         update_local(roid, lfeID, 2*lfeID.order() + 1);
     265            0 :                 }
     266              : 
     267              :         /// update Geometry for corners
     268            0 :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner)
     269              :                 {
     270            0 :                         update(pElem, vCorner, m_lfeID, m_quadOrder);
     271            0 :                 }
     272              : 
     273              :         /// update Geometry for corners
     274              :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner,
     275              :                                         const LFEID& lfeID, size_t orderQuad);
     276            0 :                 void update(GridObject* pElem, const MathVector<worldDim>* vCorner,
     277              :                                         const LFEID& lfeID){
     278            0 :                         update(pElem, vCorner, lfeID, 2*lfeID.order() + 1);
     279            0 :                 }
     280              : 
     281              :         public:
     282              :                 ///     boundary face
     283              :                 class BF
     284              :                 {
     285              :                         public:
     286            0 :                                 BF() {}
     287              : 
     288              :                                 /// outer normal on bf. Norm is equal to area
     289            0 :                                 inline const MathVector<worldDim>& normal() const {return Normal;} // includes area
     290              : 
     291              :                                 /// volume of bf
     292            0 :                                 inline number volume() const {return Vol;}
     293              : 
     294              :                                 /// number of integration points on scvf
     295            0 :                                 inline size_t num_ip() const {return nip;}
     296              : 
     297              :                                 ///     integration weight
     298            0 :                                 inline number weight(size_t ip) const
     299            0 :                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip] * vWeight[ip];}
     300              : 
     301              :                                 /// local integration point of scvf
     302            0 :                                 inline const MathVector<dim>& local_ip(size_t ip) const
     303            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vLocalIP[ip];}
     304              : 
     305              :                                 /// global integration point of scvf
     306            0 :                                 inline const MathVector<worldDim>& global_ip(size_t ip) const
     307            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vGlobalIP[ip];}
     308              : 
     309              :                                 /// Transposed Inverse of Jacobian in integration point
     310            0 :                                 inline const MathMatrix<worldDim,dim>& JTInv(size_t ip) const
     311            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vJtInv[ip];}
     312              : 
     313              :                                 /// Determinant of Jacobian in integration point
     314            0 :                                 inline number detJ(size_t ip) const
     315            0 :                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vDetJ[ip];}
     316              : 
     317              :                                 /// number of shape functions
     318            0 :                                 inline size_t num_sh() const {return nsh;}
     319              : 
     320              :                                 /// value of shape function i in integration point
     321            0 :                                 inline number shape(size_t ip, size_t sh) const
     322            0 :                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return vvShape[ip][sh];}
     323              : 
     324              :                                 /// vector of shape functions in ip point
     325            0 :                                 inline const number* shape_vector(size_t ip) const
     326            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvShape[ip][0];}
     327              : 
     328              :                                 /// value of local gradient of shape function i in integration point
     329            0 :                                 inline const MathVector<dim>& local_grad(size_t ip, size_t sh) const
     330              :                                                                 {UG_ASSERT(sh < num_sh(), "Invalid index");
     331            0 :                                                                 UG_ASSERT(ip<num_ip(), "Wrong index"); return vvLocalGrad[ip][sh];}
     332              : 
     333              :                                 /// vector of local gradients in ip point
     334            0 :                                 inline const MathVector<dim>* local_grad_vector(size_t ip) const
     335            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvLocalGrad[ip][0];}
     336              : 
     337              :                                 /// value of global gradient of shape function i in integration point
     338            0 :                                 inline const MathVector<worldDim>& global_grad(size_t ip, size_t sh) const
     339              :                                                                 {UG_ASSERT(sh < num_sh(), "Invalid index");
     340            0 :                                                                 UG_ASSERT(ip<num_ip(), "Wrong index"); return vvGlobalGrad[ip][sh];}
     341              : 
     342              :                                 /// vector of global gradients in ip point
     343            0 :                                 inline const MathVector<worldDim>* global_grad_vector(size_t ip) const
     344            0 :                                                                 {UG_ASSERT(ip<num_ip(), "Wrong index"); return &vvGlobalGrad[ip][0];}
     345              : 
     346              :                         protected:
     347              :                                 /// let outer class access private members
     348              :                                 friend class DimFEGeometry<worldDim, dim>;
     349              : 
     350              :                                 size_t nip;
     351              :                                 std::vector<MathVector<dim> > vLocalIP; // local integration point (size: nip)
     352              :                                 std::vector<MathVector<worldDim> > vGlobalIP; // global integration point (size: nip)
     353              :                                 const number* vWeight; // weight at ip
     354              :                                 MathVector<worldDim> Normal; // normal (incl. area)
     355              :                                 number Vol; // volume of bf
     356              :                                 std::vector<MathMatrix<worldDim,dim> > vJtInv; // Jacobian transposed at ip (size: nip)
     357              :                                 std::vector<number> vDetJ; // Jacobian det at ip (size: nip)
     358              : 
     359              :                                 size_t nsh;
     360              :                                 std::vector<std::vector<number> > vvShape; // shapes at ip (size: nip x nsh)
     361              :                                 std::vector<std::vector<MathVector<dim> > > vvLocalGrad; // local grad at ip (size: nip x nsh)
     362              :                                 std::vector<std::vector<MathVector<worldDim> > > vvGlobalGrad; // global grad at ip (size: nip x nsh)
     363              :                 };
     364              : 
     365              :                 /// update boundary data for given element
     366              :                 void update_boundary_faces(GridObject* pElem,
     367              :                                                                    const MathVector<worldDim>* vCornerCoords,
     368              :                                                                    size_t orderQuad,
     369              :                                                                    const ISubsetHandler* ish);
     370              : 
     371              :         public:
     372              :         /// add subset that is interpreted as boundary subset.
     373            0 :                 inline void add_boundary_subset(int subsetIndex) {m_mapVectorBF[subsetIndex];}
     374              : 
     375              :         /// removes subset that is interpreted as boundary subset.
     376            0 :                 inline void remove_boundary_subset(int subsetIndex) {m_mapVectorBF.erase(subsetIndex);}
     377              : 
     378              :         /// reset all boundary subsets
     379            0 :                 inline void clear_boundary_subsets() {m_mapVectorBF.clear();}
     380              : 
     381              :         /// number of registered boundary subsets
     382            0 :                 inline size_t num_boundary_subsets() {return m_mapVectorBF.size();}
     383              : 
     384              :         /// number of all boundary faces
     385            0 :                 inline size_t num_bf() const
     386              :                 {
     387              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     388              :                         size_t num = 0;
     389            0 :                         for ( it=m_mapVectorBF.begin() ; it != m_mapVectorBF.end(); it++ )
     390            0 :                                 num += (*it).second.size();
     391            0 :                         return num;
     392              :                 }
     393              : 
     394              :         /// number of boundary faces on subset 'subsetIndex'
     395            0 :                 inline size_t num_bf(int si) const
     396              :                 {
     397              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     398              :                         it = m_mapVectorBF.find(si);
     399            0 :                         if(it == m_mapVectorBF.end()) return 0;
     400            0 :                         else return (*it).second.size();
     401              :                 }
     402              : 
     403              :         /// returns the boundary face i for subsetIndex
     404            0 :                 inline const BF& bf(int si, size_t i) const
     405              :                 {
     406              :                         UG_ASSERT(i < num_bf(si), "Invalid index.");
     407              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     408              :                         it = m_mapVectorBF.find(si);
     409            0 :                         if(it == m_mapVectorBF.end()) UG_THROW("DimFVGeom: No BndSubset: "<<si);
     410            0 :                         return (*it).second[i];
     411              :                 }
     412              : 
     413              :         /// returns reference to vector of boundary faces for subsetIndex
     414            0 :                 inline const std::vector<BF>& bf(int si) const
     415              :                 {
     416              :                         typename std::map<int, std::vector<BF> >::const_iterator it;
     417              :                         it = m_mapVectorBF.find(si);
     418            0 :                         if(it == m_mapVectorBF.end()) return m_vEmptyVectorBF;
     419            0 :                         return (*it).second;
     420              :                 }
     421              : 
     422              :         protected:
     423              :                 std::map<int, std::vector<BF> > m_mapVectorBF;
     424              :                 std::vector<BF> m_vEmptyVectorBF;
     425              : 
     426              :         protected:
     427              :         ///     current reference object id the local values are prepared for
     428              :                 ReferenceObjectID m_roid;
     429              : 
     430              :         ///     current element
     431              :                 GridObject* m_pElem;
     432              : 
     433              :         ///     current integration order
     434              :                 int m_quadOrder;
     435              : 
     436              :         ///     current local finite element id
     437              :                 LFEID m_lfeID;
     438              : 
     439              :         ///     number of integration point
     440              :                 size_t m_nip;
     441              : 
     442              :         ///     local quadrature points
     443              :                 const MathVector<dim>* m_vIPLocal;
     444              : 
     445              :         ///     local quadrature weights
     446              :                 const number* m_vQuadWeight;
     447              : 
     448              :         ///     global integration points (size = nip)
     449              :                 std::vector<MathVector<worldDim> > m_vIPGlobal;
     450              : 
     451              :         ///     jacobian of transformation at ip (size = nip)
     452              :                 std::vector<MathMatrix<worldDim,dim> > m_vJTInv;
     453              : 
     454              :         ///     determinant of transformation at ip (size = nip)
     455              :                 std::vector<number> m_vDetJ;
     456              : 
     457              :         ///     number of shape functions
     458              :                 size_t m_nsh;
     459              : 
     460              :         ///     shape functions evaluated at ip (size = nip x nsh)
     461              :                 std::vector<std::vector<number> > m_vvShape;
     462              : 
     463              :         ///     global gradient evaluated at ip (size = nip x nsh)
     464              :                 std::vector<std::vector<MathVector<dim> > > m_vvGradLocal;
     465              : 
     466              :         ///     local gradient evaluated at ip (size = nip x nsh)
     467              :                 std::vector<std::vector<MathVector<worldDim> > > m_vvGradGlobal;
     468              : };
     469              : 
     470              : } // end namespace ug
     471              : 
     472              : #include "fe_geom_impl.h"
     473              : 
     474              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__DISC_HELPER__FINITE_ELEMENT_GEOMETRY__ */
        

Generated by: LCOV version 2.0-1