LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/elem_disc/neumann_boundary/fv - neumann_boundary_fv.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 183 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 168 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              : #include "neumann_boundary_fv.h"
      34              : #include "lib_disc/spatial_disc/disc_util/fvho_geom.h"
      35              : #include "lib_disc/spatial_disc/disc_util/geom_provider.h"
      36              : 
      37              : namespace ug{
      38              : 
      39              : ////////////////////////////////////////////////////////////////////////////////
      40              : //      Constructor
      41              : ////////////////////////////////////////////////////////////////////////////////
      42              : 
      43              : template<typename TDomain>
      44            0 : NeumannBoundaryFV<TDomain>::NeumannBoundaryFV(const char* function)
      45              :  :NeumannBoundaryBase<TDomain>(function),
      46            0 :   m_order(1), m_lfeID(LFEID::LAGRANGE, TDomain::dim, m_order)
      47              : {
      48            0 :         register_all_funcs(m_order);
      49            0 : }
      50              : 
      51              : template<typename TDomain>
      52            0 : void NeumannBoundaryFV<TDomain>::
      53              : prepare_setting(const std::vector<LFEID>& vLfeID, bool bNonRegularGrid)
      54              : {
      55            0 :         if(bNonRegularGrid)
      56            0 :                 UG_THROW("NeumannBoundary: Hanging Nodes not implemented.");
      57              : 
      58              : //      check number
      59            0 :         if(vLfeID.size() != 1)
      60            0 :                 UG_THROW("NeumannBoundaryFV: Need exactly 1 function.");
      61              : 
      62            0 :         if(vLfeID[0].type() != LFEID::LAGRANGE)
      63            0 :                 UG_THROW("NeumannBoundary: FV Scheme only implemented for Lagrange-type elements.");
      64              : 
      65              : //      check that not ADAPTIVE
      66            0 :         if(vLfeID[0].order() < 1)
      67            0 :                 UG_THROW("NeumannBoundary: Adaptive order not implemented.");
      68              : 
      69              : //      set order
      70            0 :         m_lfeID = vLfeID[0];
      71            0 :         m_order = vLfeID[0].order();
      72              : 
      73            0 :         register_all_funcs(m_order);
      74            0 : }
      75              : 
      76              : template<typename TDomain>
      77            0 : void NeumannBoundaryFV<TDomain>::
      78              : add(SmartPtr<CplUserData<number, dim> > data, const char* BndSubsets, const char* InnerSubsets)
      79              : {
      80            0 :         m_vNumberData.push_back(NumberData(data, BndSubsets, InnerSubsets, this));
      81            0 :         this->add_inner_subsets(InnerSubsets);
      82            0 : }
      83              : 
      84              : template<typename TDomain>
      85            0 : void NeumannBoundaryFV<TDomain>::
      86              : add(SmartPtr<CplUserData<number, dim, bool> > user, const char* BndSubsets, const char* InnerSubsets)
      87              : {
      88            0 :         m_vBNDNumberData.push_back(BNDNumberData(user, BndSubsets, InnerSubsets));
      89            0 :         this->add_inner_subsets(InnerSubsets);
      90            0 : }
      91              : 
      92              : template<typename TDomain>
      93            0 : void NeumannBoundaryFV<TDomain>::
      94              : add(SmartPtr<CplUserData<MathVector<dim>, dim> > user, const char* BndSubsets, const char* InnerSubsets)
      95              : {
      96            0 :         m_vVectorData.push_back(VectorData(user, BndSubsets, InnerSubsets));
      97            0 :         this->add_inner_subsets(InnerSubsets);
      98            0 : }
      99              : 
     100              : template<typename TDomain>
     101            0 : void NeumannBoundaryFV<TDomain>::update_subset_groups()
     102              : {
     103            0 :         for(size_t i = 0; i < m_vNumberData.size(); ++i)
     104            0 :                 base_type::update_subset_groups(m_vNumberData[i]);
     105            0 :         for(size_t i = 0; i < m_vBNDNumberData.size(); ++i)
     106            0 :                 base_type::update_subset_groups(m_vBNDNumberData[i]);
     107            0 :         for(size_t i = 0; i < m_vVectorData.size(); ++i)
     108            0 :                 base_type::update_subset_groups(m_vVectorData[i]);
     109            0 : }
     110              : 
     111              : 
     112              : ////////////////////////////////////////////////////////////////////////////////
     113              : //      assembling functions
     114              : ////////////////////////////////////////////////////////////////////////////////
     115              : 
     116              : template<typename TDomain>
     117              : template<typename TElem, typename TFVGeom>
     118            0 : void NeumannBoundaryFV<TDomain>::
     119              : prep_elem_loop(const ReferenceObjectID roid, const int si)
     120              : {
     121            0 :         update_subset_groups();
     122            0 :         m_si = si;
     123              : 
     124              : //      register subsetIndex at Geometry
     125            0 :         TFVGeom& geo = GeomProvider<TFVGeom>::get(m_lfeID,m_order);
     126              : 
     127              :         try{
     128            0 :                 geo.update_local(roid, m_lfeID);
     129              :         }
     130            0 :         UG_CATCH_THROW("NeumannBoundaryFV::prep_elem_loop:"
     131              :                                                 " Cannot update Finite Volume Geometry.");
     132              : 
     133              : //      request subset indices as boundary subset. This will force the
     134              : //      creation of boundary subsets when calling geo.update
     135              : 
     136            0 :         for(size_t i = 0; i < m_vNumberData.size(); ++i){
     137            0 :                 if(!m_vNumberData[i].InnerSSGrp.contains(m_si)) continue;
     138            0 :                 for(size_t s = 0; s < m_vNumberData[i].BndSSGrp.size(); ++s){
     139              :                         const int si = m_vNumberData[i].BndSSGrp[s];
     140            0 :                         geo.add_boundary_subset(si);
     141              :                 }
     142              :         }
     143            0 :         for(size_t i = 0; i < m_vBNDNumberData.size(); ++i){
     144            0 :                 if(!m_vBNDNumberData[i].InnerSSGrp.contains(m_si)) continue;
     145            0 :                 for(size_t s = 0; s < m_vBNDNumberData[i].BndSSGrp.size(); ++s){
     146              :                         const int si = m_vBNDNumberData[i].BndSSGrp[s];
     147            0 :                         geo.add_boundary_subset(si);
     148              :                 }
     149              :         }
     150            0 :         for(size_t i = 0; i < m_vVectorData.size(); ++i){
     151            0 :                 if(!m_vVectorData[i].InnerSSGrp.contains(m_si)) continue;
     152            0 :                 for(size_t s = 0; s < m_vVectorData[i].BndSSGrp.size(); ++s){
     153              :                         const int si = m_vVectorData[i].BndSSGrp[s];
     154            0 :                         geo.add_boundary_subset(si);
     155              :                 }
     156              :         }
     157              : 
     158              : //      clear imports, since we will set them afterwards
     159              :         this->clear_imports();
     160              : 
     161              :         ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     162              : 
     163              : //      set lin defect fct for imports
     164            0 :         for(size_t data = 0; data < m_vNumberData.size(); ++data)
     165              :         {
     166            0 :                 if(!m_vNumberData[data].InnerSSGrp.contains(m_si)) continue;
     167            0 :                 m_vNumberData[data].import.set_fct(id,
     168              :                                                    &m_vNumberData[data],
     169              :                                                    &NumberData::template lin_def<TElem, TFVGeom>);
     170              : 
     171            0 :                 this->register_import(m_vNumberData[data].import);
     172              :                 m_vNumberData[data].import.set_rhs_part();
     173              :         }
     174            0 : }
     175              : 
     176              : template<typename TDomain>
     177              : template<typename TElem, typename TFVGeom>
     178            0 : void NeumannBoundaryFV<TDomain>::
     179              : prep_elem(const LocalVector& u, GridObject* elem, const ReferenceObjectID roid, const MathVector<dim> vCornerCoords[])
     180              : {
     181              : //  update Geometry for this element
     182            0 :         TFVGeom& geo = GeomProvider<TFVGeom>::get(m_lfeID,m_order);
     183              :         try{
     184            0 :                 geo.update(elem,vCornerCoords,&(this->subset_handler()));
     185              :         }
     186            0 :         UG_CATCH_THROW("NeumannBoundaryFV::prep_elem: "
     187              :                                                 "Cannot update Finite Volume Geometry.");
     188              : 
     189            0 :         for(size_t i = 0; i < m_vNumberData.size(); ++i)
     190            0 :                 if(m_vNumberData[i].InnerSSGrp.contains(m_si))
     191            0 :                         m_vNumberData[i].template extract_bip<TElem, TFVGeom>(geo);
     192            0 : }
     193              : 
     194              : template<typename TDomain>
     195              : template<typename TElem, typename TFVGeom>
     196            0 : void NeumannBoundaryFV<TDomain>::
     197              : add_rhs_elem(LocalVector& d, GridObject* elem, const MathVector<dim> vCornerCoords[])
     198              : {
     199            0 :         TFVGeom& geo = GeomProvider<TFVGeom>::get(m_lfeID,m_order);
     200              :         typedef typename TFVGeom::BF BF;
     201              : 
     202              : //      Number Data
     203            0 :         for(size_t data = 0; data < m_vNumberData.size(); ++data){
     204            0 :                 if(!m_vNumberData[data].InnerSSGrp.contains(m_si)) continue;
     205              :                 size_t ip = 0;
     206            0 :                 for(size_t s = 0; s < m_vNumberData[data].BndSSGrp.size(); ++s){
     207              :                         const int si = m_vNumberData[data].BndSSGrp[s];
     208              :                         const std::vector<BF>& vBF = geo.bf(si);
     209              : 
     210            0 :                         for(size_t b = 0; b < vBF.size(); ++b){
     211            0 :                                 const int co = vBF[b].node_id();
     212              : 
     213            0 :                                 for(size_t i = 0; i < vBF[b].num_ip(); ++i, ++ip){
     214            0 :                                         d(_C_, co) -= m_vNumberData[data].import[ip]
     215            0 :                                                      * vBF[b].volume() * vBF[b].weight(i);
     216              :                                 }
     217              :                         }
     218              :                 }
     219              :         }
     220              : 
     221              : //      conditional Number Data
     222            0 :         for(size_t data = 0; data < m_vBNDNumberData.size(); ++data){
     223            0 :                 if(!m_vBNDNumberData[data].InnerSSGrp.contains(m_si)) continue;
     224            0 :                 for(size_t s = 0; s < m_vBNDNumberData[data].BndSSGrp.size(); ++s)   {
     225              :                         const int si = m_vBNDNumberData[data].BndSSGrp[s];
     226              :                         const std::vector<BF>& vBF = geo.bf(si);
     227              : 
     228            0 :                         for(size_t b = 0; b < vBF.size(); ++b){
     229            0 :                                 number val = 0.0;
     230            0 :                                 const int co = vBF[b].node_id();
     231              : 
     232            0 :                                 for(size_t i = 0; i < vBF[b].num_ip(); ++i){
     233            0 :                                         if(!(*m_vBNDNumberData[data].functor)(val, vBF[b].global_ip(i), this->time(), si))
     234            0 :                                                 continue;
     235              : 
     236            0 :                                         d(_C_, co) -= val * vBF[b].volume() * vBF[b].weight(i);
     237              :                                 }
     238              :                         }
     239              :                 }
     240              :         }
     241              : 
     242              : //      vector data
     243            0 :         for(size_t data = 0; data < m_vVectorData.size(); ++data){
     244            0 :                 if(!m_vVectorData[data].InnerSSGrp.contains(m_si)) continue;
     245            0 :                 for(size_t s = 0; s < m_vVectorData[data].BndSSGrp.size(); ++s){
     246              :                         const int si = m_vVectorData[data].BndSSGrp[s];
     247              :                         const std::vector<BF>& vBF = geo.bf(si);
     248              : 
     249            0 :                         for(size_t b = 0; b < vBF.size(); ++b){
     250              :                                 MathVector<dim> val;
     251            0 :                                 const int co = vBF[b].node_id();
     252              : 
     253            0 :                                 for(size_t i = 0; i < vBF[b].num_ip(); ++i){
     254            0 :                                         (*m_vVectorData[data].functor)(val, vBF[b].global_ip(i), this->time(), si);
     255              : 
     256            0 :                                         d(_C_, co) -= vBF[b].weight(i) * VecDot(val, vBF[b].normal());
     257              :                                 }
     258              :                         }
     259              :                 }
     260              :         }
     261            0 : }
     262              : 
     263              : template<typename TDomain>
     264              : template<typename TElem, typename TFVGeom>
     265            0 : void NeumannBoundaryFV<TDomain>::
     266              : finish_elem_loop()
     267              : {
     268              : //      remove subsetIndex from Geometry
     269            0 :         TFVGeom& geo = GeomProvider<TFVGeom>::get(m_lfeID,m_order);
     270              : 
     271              : //      unrequest subset indices as boundary subset. This will force the
     272              : //      creation of boundary subsets when calling geo.update
     273              : 
     274            0 :         for(size_t i = 0; i < m_vNumberData.size(); ++i){
     275            0 :                 if(!m_vNumberData[i].InnerSSGrp.contains(m_si)) continue;
     276            0 :                 for(size_t s = 0; s < m_vNumberData[i].BndSSGrp.size(); ++s){
     277              :                         const int si = m_vNumberData[i].BndSSGrp[s];
     278            0 :                         geo.remove_boundary_subset(si);
     279              :                         geo.reset_curr_elem();
     280              :                 }
     281              :         }
     282              : 
     283            0 :         for(size_t i = 0; i < m_vBNDNumberData.size(); ++i){
     284            0 :                 if(!m_vBNDNumberData[i].InnerSSGrp.contains(m_si)) continue;
     285            0 :                 for(size_t s = 0; s < m_vBNDNumberData[i].BndSSGrp.size(); ++s){
     286              :                         const int si = m_vBNDNumberData[i].BndSSGrp[s];
     287            0 :                         geo.remove_boundary_subset(si);
     288              :                         geo.reset_curr_elem();
     289              :                 }
     290              :         }
     291              : 
     292            0 :         for(size_t i = 0; i < m_vVectorData.size(); ++i){
     293            0 :                 if(!m_vVectorData[i].InnerSSGrp.contains(m_si)) continue;
     294            0 :                 for(size_t s = 0; s < m_vVectorData[i].BndSSGrp.size(); ++s){
     295              :                         const int si = m_vVectorData[i].BndSSGrp[s];
     296            0 :                         geo.remove_boundary_subset(si);
     297              :                         geo.reset_curr_elem();
     298              :                 }
     299              :         }
     300            0 : }
     301              : 
     302              : ////////////////////////////////////////////////////////////////////////////////
     303              : // Number Data
     304              : ////////////////////////////////////////////////////////////////////////////////
     305              : 
     306              : template<typename TDomain>
     307              : template<typename TElem, typename TFVGeom>
     308            0 : void NeumannBoundaryFV<TDomain>::NumberData::
     309              : lin_def(const LocalVector& u,
     310              :             std::vector<std::vector<number> > vvvLinDef[],
     311              :             const size_t nip)
     312              : {
     313              : //  get finite volume geometry
     314            0 :         const TFVGeom& geo = GeomProvider<TFVGeom>::get(This->m_lfeID,This->m_order);
     315              :         typedef typename TFVGeom::BF BF;
     316              : 
     317              :         size_t ip = 0;
     318            0 :         for(size_t s = 0; s < this->BndSSGrp.size(); ++s)
     319              :         {
     320              :                 const int si = this->BndSSGrp[s];
     321              :                 const std::vector<BF>& vBF = geo.bf(si);
     322            0 :                 for(size_t i = 0; i < vBF.size(); ++i){
     323            0 :                         const int co = vBF[i].node_id();
     324            0 :                         vvvLinDef[ip][_C_][co] -= vBF[i].volume();
     325              :                 }
     326              :         }
     327            0 : }
     328              : 
     329              : template<typename TDomain>
     330              : template<typename TElem, typename TFVGeom>
     331            0 : void NeumannBoundaryFV<TDomain>::NumberData::
     332              : extract_bip(const TFVGeom& geo)
     333              : {
     334              :         typedef typename TFVGeom::BF BF;
     335              :         static const int locDim = TElem::dim;
     336              : 
     337              :         std::vector<MathVector<locDim> >* vLocIP = local_ips<locDim>();
     338              : 
     339              :         vLocIP->clear();
     340              :         vGloIP.clear();
     341            0 :         for(size_t s = 0; s < this->BndSSGrp.size(); s++)
     342              :         {
     343              :                 const int si = this->BndSSGrp[s];
     344              :                 const std::vector<BF>& vBF = geo.bf(si);
     345            0 :                 for(size_t i = 0; i < vBF.size(); ++i)
     346              :                 {
     347              :                         const BF& bf = vBF[i];
     348            0 :                         for(size_t ip = 0; ip < bf.num_ip(); ++ip){
     349            0 :                                 vLocIP->push_back(bf.local_ip(ip));
     350            0 :                                 vGloIP.push_back(bf.global_ip(ip));
     351              :                         }
     352              :                 }
     353              :         }
     354              : 
     355            0 :         import.template set_local_ips<locDim>(&(*vLocIP)[0], vLocIP->size());
     356            0 :         import.set_global_ips(&vGloIP[0], vGloIP.size());
     357            0 : }
     358              : 
     359              : template<typename TDomain>
     360              : template <int refDim>
     361              : std::vector<MathVector<refDim> >* NeumannBoundaryFV<TDomain>::NumberData::local_ips()
     362              : {
     363              :         switch (refDim)
     364              :         {
     365            0 :                 case 1: return (std::vector<MathVector<refDim> >*)(&vLocIP_dim1);
     366            0 :                 case 2: return (std::vector<MathVector<refDim> >*)(&vLocIP_dim2);
     367            0 :                 case 3: return (std::vector<MathVector<refDim> >*)(&vLocIP_dim3);
     368              :         }
     369              : }
     370              : 
     371              : ////////////////////////////////////////////////////////////////////////////////
     372              : //      register assemble functions
     373              : ////////////////////////////////////////////////////////////////////////////////
     374              : 
     375              : #ifdef UG_DIM_1
     376              : template<>
     377            0 : void NeumannBoundaryFV<Domain1d>::register_all_funcs(int order)
     378              : {
     379              :         // Edge
     380            0 :         register_func<RegularEdge, DimFVGeometry<dim, 1> >();
     381            0 : }
     382              : #endif
     383              : 
     384              : #ifdef UG_DIM_2
     385              : template<>
     386            0 : void NeumannBoundaryFV<Domain2d>::register_all_funcs(int order)
     387              : {
     388              : // Edge
     389            0 :         register_func<RegularEdge, DimFVGeometry<dim, 1> >();
     390              : 
     391              : //      Triangle
     392            0 :         switch(order)
     393              :         {
     394            0 :                 case 1: {typedef FVGeometry<1, Triangle, dim> FVGeom;
     395            0 :                                  register_func<Triangle, FVGeom >(); break;}
     396            0 :                 case 2: {typedef FVGeometry<2, Triangle, dim> FVGeom;
     397            0 :                                  register_func<Triangle, FVGeom >(); break;}
     398            0 :                 case 3: {typedef FVGeometry<3, Triangle, dim> FVGeom;
     399            0 :                                  register_func<Triangle, FVGeom >(); break;}
     400            0 :                 default: {typedef DimFVGeometry<dim, 2> FVGeom;
     401            0 :                                  register_func<Triangle, FVGeom >(); break;}
     402              :         }
     403              : 
     404              : //      Quadrilateral
     405            0 :         switch(order) {
     406            0 :                 case 1: {typedef FVGeometry<1, Quadrilateral, dim> FVGeom;
     407            0 :                                  register_func<Quadrilateral, FVGeom >(); break;}
     408            0 :                 case 2: {typedef FVGeometry<2, Quadrilateral, dim> FVGeom;
     409            0 :                                  register_func<Quadrilateral, FVGeom >(); break;}
     410            0 :                 case 3: {typedef FVGeometry<3, Quadrilateral, dim> FVGeom;
     411            0 :                                  register_func<Quadrilateral, FVGeom >(); break;}
     412            0 :                 default: {typedef DimFVGeometry<dim, 2> FVGeom;
     413            0 :                                   register_func<Quadrilateral, FVGeom >(); break;}
     414              :         }
     415            0 : }
     416              : #endif
     417              : 
     418              : #ifdef UG_DIM_3
     419              : template<>
     420            0 : void NeumannBoundaryFV<Domain3d>::register_all_funcs(int order)
     421              : {
     422              : // Edge
     423            0 :         register_func<RegularEdge, DimFVGeometry<dim, 1> >();
     424              : 
     425              : //      Tetrahedron
     426            0 :         switch(order)
     427              :         {
     428            0 :                 case 1: {typedef FVGeometry<1, Tetrahedron, dim> FVGeom;
     429            0 :                                  register_func<Tetrahedron, FVGeom >(); break;}
     430            0 :                 case 2: {typedef FVGeometry<2, Tetrahedron, dim> FVGeom;
     431            0 :                                  register_func<Tetrahedron, FVGeom >(); break;}
     432            0 :                 case 3: {typedef FVGeometry<3, Tetrahedron, dim> FVGeom;
     433            0 :                                  register_func<Tetrahedron, FVGeom >(); break;}
     434            0 :                 default: {typedef DimFVGeometry<dim, 3> FVGeom;
     435            0 :                                   register_func<Tetrahedron, FVGeom >(); break;}
     436              :         }
     437              : 
     438              : //      Prism
     439            0 :         switch(order) {
     440            0 :                 case 1: {typedef FVGeometry<1, Prism, dim> FVGeom;
     441            0 :                                  register_func<Prism, FVGeom >(); break;}
     442            0 :                 default: {typedef DimFVGeometry<dim, 3> FVGeom;
     443            0 :                                   register_func<Prism, FVGeom >(); break;}
     444              :         }
     445              : 
     446              : //      Hexahedron
     447            0 :         switch(order)
     448              :         {
     449            0 :                 case 1: {typedef FVGeometry<1, Hexahedron, dim> FVGeom;
     450            0 :                                  register_func<Hexahedron, FVGeom >(); break;}
     451            0 :                 case 2: {typedef FVGeometry<2, Hexahedron, dim> FVGeom;
     452            0 :                                  register_func<Hexahedron, FVGeom >(); break;}
     453            0 :                 case 3: {typedef FVGeometry<3, Hexahedron, dim> FVGeom;
     454            0 :                                  register_func<Hexahedron, FVGeom >(); break;}
     455            0 :                 default: {typedef DimFVGeometry<dim, 3> FVGeom;
     456            0 :                                   register_func<Hexahedron, FVGeom >(); break;}
     457              :         }
     458            0 : }
     459              : #endif
     460              : 
     461              : template<typename TDomain>
     462              : template<typename TElem, typename TFVGeom>
     463            0 : void NeumannBoundaryFV<TDomain>::register_func()
     464              : {
     465              :         ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     466              :         typedef this_type T;
     467              : 
     468              :         this->clear_add_fct(id);
     469              : 
     470              :         this->set_prep_elem_loop_fct(id, &T::template prep_elem_loop<TElem, TFVGeom>);
     471              :         this->set_prep_elem_fct(      id, &T::template prep_elem<TElem, TFVGeom>);
     472              :         this->set_add_rhs_elem_fct(   id, &T::template add_rhs_elem<TElem, TFVGeom>);
     473              :         this->set_fsh_elem_loop_fct( id, &T::template finish_elem_loop<TElem, TFVGeom>);
     474              : 
     475              :         this->set_add_jac_A_elem_fct(         id, &T::template add_jac_A_elem<TElem, TFVGeom>);
     476              :         this->set_add_jac_M_elem_fct(         id, &T::template add_jac_M_elem<TElem, TFVGeom>);
     477              :         this->set_add_def_A_elem_fct(         id, &T::template add_def_A_elem<TElem, TFVGeom>);
     478              :         this->set_add_def_M_elem_fct(         id, &T::template add_def_M_elem<TElem, TFVGeom>);
     479            0 : }
     480              : 
     481              : ////////////////////////////////////////////////////////////////////////////////
     482              : //      explicit template instantiations
     483              : ////////////////////////////////////////////////////////////////////////////////
     484              : 
     485              : #ifdef UG_DIM_1
     486              : template class NeumannBoundaryFV<Domain1d>;
     487              : #endif
     488              : #ifdef UG_DIM_2
     489              : template class NeumannBoundaryFV<Domain2d>;
     490              : #endif
     491              : #ifdef UG_DIM_3
     492              : template class NeumannBoundaryFV<Domain3d>;
     493              : #endif
     494              : 
     495              : } // namespace ug
     496              : 
        

Generated by: LCOV version 2.0-1