LCOV - code coverage report
Current view: top level - /builds/ug4-project/ugcore/ug4-new/plugins/ConvectionDiffusion/fractfv1 - convection_diffusion_fractfv1.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 425 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 218 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2018:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Dmitry Logashenko
       4              :  * Based on the modules by Andreas Vogel
       5              :  * 
       6              :  * This file is part of UG4.
       7              :  * 
       8              :  * UG4 is free software: you can redistribute it and/or modify it under the
       9              :  * terms of the GNU Lesser General Public License version 3 (as published by the
      10              :  * Free Software Foundation) with the following additional attribution
      11              :  * requirements (according to LGPL/GPL v3 §7):
      12              :  * 
      13              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      14              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      15              :  * 
      16              :  * (2) The following notice must be displayed at a prominent place in the
      17              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      18              :  * 
      19              :  * (3) The following bibliography is recommended for citation and must be
      20              :  * preserved in all covered files:
      21              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      22              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      23              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      24              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      25              :  *   flexible software system for simulating pde based models on high performance
      26              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      27              :  * 
      28              :  * This program is distributed in the hope that it will be useful,
      29              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      30              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      31              :  * GNU Lesser General Public License for more details.
      32              :  */
      33              : 
      34              : #include "convection_diffusion_fractfv1.h"
      35              : 
      36              : #include "lib_disc/spatial_disc/disc_util/geom_provider.h"
      37              : #include "lib_disc/spatial_disc/disc_util/fv1_geom.h"
      38              : #include "lib_disc/spatial_disc/disc_util/hfv1_geom.h"
      39              : #include "lib_disc/spatial_disc/disc_util/conv_shape.h"
      40              : 
      41              : namespace ug{
      42              : namespace ConvectionDiffusionPlugin{
      43              : 
      44              : ////////////////////////////////////////////////////////////////////////////////
      45              : //      general
      46              : ////////////////////////////////////////////////////////////////////////////////
      47              : 
      48              : template<typename TDomain>
      49            0 : ConvectionDiffusionFractFV1<TDomain>::
      50              : ConvectionDiffusionFractFV1 (const char* functions, const char* subsets)
      51              : :       ConvectionDiffusionBase<TDomain> (functions, subsets),
      52            0 :         m_spConvShape (new ConvectionShapesNoUpwind<dim>)
      53              : {
      54              : //      initialize the fracture-specific input-export parameters that are not in the base
      55              :         m_imAperture.set_comp_lin_defect (false);
      56              : 
      57              : //      register the fracture-specific input-export parameters that are not in the base
      58            0 :         this->register_import (m_imAperture);
      59            0 :         this->register_import (m_imOrthoDiffusion);
      60            0 :         this->register_import (m_imOrthoVelocity);
      61            0 :         this->register_import (m_imOrthoFlux);
      62            0 :         this->register_import (m_imOrthoVectorSource);
      63              : 
      64              : //      register the element assembling functions
      65              :         register_all_funcs ();
      66            0 : }
      67              : 
      68              : ////////////////////////////////////////////////////////////////////////////////
      69              : //      Local discretization interface
      70              : ////////////////////////////////////////////////////////////////////////////////
      71              : 
      72              : /// checks the grid and the shape functions
      73              : template<typename TDomain>
      74            0 : void ConvectionDiffusionFractFV1<TDomain>::prepare_setting
      75              : (
      76              :         const std::vector<LFEID> & vLfeID,
      77              :         bool bNonRegular
      78              : )
      79              : {
      80              : //      check the grid
      81            0 :         if (bNonRegular)
      82            0 :                 UG_THROW ("ERROR in ConvectionDiffusionFractFV1::prepare_setting:"
      83              :                                 " This discretization does not support hanging nodes.\n");
      84              : 
      85              : //      check number of the components
      86            0 :         if (vLfeID.size () != 1)
      87            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prepare_setting: Wrong number of functions given. Need exactly 1.");
      88              : 
      89              : //      check whether these are the LagrangeP1 elements
      90              :         if (vLfeID[0] != LFEID(LFEID::LAGRANGE, dim, 1))
      91            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prepare_setting: ConvectionDiffusion FV Scheme only implemented for 1st order.");
      92            0 : }
      93              : 
      94              : ////////////////////////////////////////////////////////////////////////////////
      95              : // Assembling functions
      96              : ////////////////////////////////////////////////////////////////////////////////
      97              : 
      98              : ///     computes and returns the upwind shapes for the given velocity
      99              : template<typename TDomain>
     100              : const typename ConvectionDiffusionFractFV1<TDomain>::conv_shape_type&
     101            0 : ConvectionDiffusionFractFV1<TDomain>::get_updated_conv_shapes
     102              : (
     103              :         bool computeDeriv ///< whether to compute the derivatives of the shapes
     104              : )
     105              : {
     106            0 :         if(m_imVelocity.data_given())
     107              :         {
     108              :         //      get diffusion at ips
     109              :                 const MathMatrix<dim, dim>* vDiffusion = NULL;
     110            0 :                 if (m_imDiffusion.data_given ()) vDiffusion = m_imDiffusion.values ();
     111              : 
     112              :         //      update convection shapes
     113            0 :                 if (!m_spConvShape->update (m_pFractGeo, m_imVelocity.values (), vDiffusion, computeDeriv))
     114              :                 {
     115              :                         UG_LOG("ERROR in 'ConvectionDiffusionFractFV1::get_updated_conv_shapes': "
     116              :                                         "Cannot compute convection shapes.\n");
     117              :                 }
     118              :         }
     119              : 
     120              : //      return a const (!!) reference to the upwind
     121            0 :         return *const_cast<const IConvectionShapes<dim>*>(m_spConvShape.get());
     122              : }
     123              : 
     124              : /// prepares the loop over the elements: checks whether the parameters are set, ...
     125              : template<typename TDomain>
     126              : template<typename TElem>
     127            0 : void ConvectionDiffusionFractFV1<TDomain>::prep_elem_loop
     128              : (
     129              :         ReferenceObjectID roid, ///< only elements with this roid are looped over
     130              :         int si ///< and only in this subdomain
     131              : )
     132              : {
     133              :         typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
     134              :         
     135              : //      check the imports
     136            0 :         if (!m_imAperture.data_given())
     137            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prep_elem_loop: Missing Import 'fracture width (aperture)'.");
     138              :                 
     139              : //      check whether we are in a degenerated fracture
     140            0 :         if (! m_spFractManager.valid())
     141            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prep_elem_loop: No fracture manager specified.");
     142            0 :         if (! m_spFractManager->is_closed ())
     143            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prep_elem_loop: Fracture manager not closed.");
     144            0 :         if (! m_spFractManager->contains (si))
     145            0 :                 UG_THROW ("ConvectionDiffusionFractFV1::prep_elem_loop:"
     146              :                         " The fract. discretization is used for subset " << si << " which is not a degenerated fracture.");
     147              :         
     148              : //      check, that upwind has been set
     149            0 :         if(m_spConvShape.invalid())
     150            0 :                 UG_THROW("ConvectionDiffusionFractFV1::prep_elem_loop: Upwind has not been set.");
     151              : 
     152              : //      initialize the pointer to the FV geometry for fracture elements
     153            0 :         m_pFractGeo = &GeomProvider<TFractFVGeom>::get (LFEID (LFEID::LAGRANGE, low_dim, 1), 1);
     154              :         
     155              : //      set up local ip coordinates for corner import parameters
     156              : //      REMARK: Note that for the fracture elements, values of the corner import
     157              : //      parameters are indexed not by scv (as for the normal elements) but by
     158              : //      the corner indices in the reference element
     159            0 : }
     160              : 
     161              : template<typename TDomain>
     162              : template<typename TElem>
     163            0 : void ConvectionDiffusionFractFV1<TDomain>::fsh_elem_loop ()
     164            0 : {}
     165              : 
     166              : template<typename TDomain>
     167              : template<typename TElem>
     168            0 : void ConvectionDiffusionFractFV1<TDomain>::prep_elem
     169              : (
     170              :         const LocalVector & u, ///< local solution at the dofs associated with elem
     171              :         GridObject * elem, ///< element to prepare
     172              :         ReferenceObjectID roid,  // id of reference element used for assembling
     173              :         const position_type vCornerCoords [] ///< coordinates of the corners of the element
     174              : )
     175              : {
     176              :         typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
     177              :         
     178              :         static const int refDim = TElem::dim; // dimensionality of the element, not the side!
     179              :         TElem * pElem = static_cast<TElem*> (elem);
     180            0 :         ref_elem_type& rRefElem = Provider<ref_elem_type>::get ();
     181              : 
     182              : //      get the non-degenerated sides of the fracture element
     183              :         try
     184              :         {
     185              :                 m_spFractManager->get_layer_sides
     186            0 :                         (pElem,
     187            0 :                                 m_numFractCo, m_innerFractSide, m_innerFractSideIdx, m_innerSideCo,
     188            0 :                                 m_outerFractSide, m_outerFractSideIdx, m_outerSideCo,
     189            0 :                                 m_assCo);
     190              :         }
     191            0 :         UG_CATCH_THROW("ConvectionDiffusionFractFV1::prep_elem: Cannot find orientation of a fracture element.");
     192              :         
     193              : //      compute the FV geometry of the inner side
     194            0 :         position_type vSideCornerCoords [maxFractSideCorners]; // global side corner coords
     195              :         try
     196              :         {
     197            0 :                 for (size_t co = 0; co < m_numFractCo; co++)
     198            0 :                         vSideCornerCoords [co] = vCornerCoords [m_innerSideCo [co]];
     199            0 :                 m_pFractGeo->update (m_innerFractSide, vSideCornerCoords, &(this->subset_handler()));
     200              :         }
     201            0 :         UG_CATCH_THROW("ConvectionDiffusionFractFV1::prep_elem: Cannot update the Finite Volume Geometry for a fracture element.");
     202            0 :         size_t numSCVFip = m_pFractGeo->num_scvf_ips ();
     203              :         size_t numSCVip = m_pFractGeo->num_scv_ips ();
     204              :         
     205              : //      convert local coordinates of the side into the local coordinates of the element (for the input parameters)
     206            0 :         position_type vSideLocCornerCoords [maxFractSideCorners]; // local side corner coords
     207            0 :         position_type vSideLocSCVFipCoords [TFractFVGeom::maxNumSCVF]; // local scvf ip's in a fracture element
     208            0 :         position_type vSideLocSCVipCoords [TFractFVGeom::maxNumSCV]; // local scv ip's in a fracture element
     209              :         position_type elemLocCOE; // local coordinates of the mass center of a fracture element
     210              :         try
     211              :         {
     212              :                 DimReferenceMapping<low_dim, dim>& rMapping
     213            0 :                         = ReferenceMappingProvider::get<low_dim, dim> (m_innerFractSide->reference_object_id ());
     214            0 :                 for (size_t co = 0; co < m_numFractCo; co++)
     215            0 :                         vSideLocCornerCoords [co] = rRefElem.corner (m_innerSideCo [co]);
     216            0 :                 rMapping.update (vSideLocCornerCoords);
     217              :                 
     218            0 :                 rMapping.local_to_global (elemLocCOE, *(m_pFractGeo->coe_local ()));
     219            0 :                 rMapping.local_to_global (vSideLocSCVFipCoords, m_pFractGeo->scvf_local_ips (), numSCVFip);
     220            0 :                 rMapping.local_to_global (vSideLocSCVipCoords, m_pFractGeo->scv_local_ips (), numSCVip);
     221              :         }
     222            0 :         UG_CATCH_THROW("ConvectionDiffusionFractFV1::prep_elem: Cannot transform local side coordinates to local element coordinates in a fracture element.");
     223              :         
     224              : 
     225              : //      set local positions
     226              :         
     227            0 :         m_imDiffusion.template          set_local_ips<refDim> (vSideLocSCVFipCoords, numSCVFip);
     228            0 :         m_imVelocity.template           set_local_ips<refDim> (vSideLocSCVFipCoords, numSCVFip);
     229            0 :         m_imFlux.template                       set_local_ips<refDim> (vSideLocSCVFipCoords, numSCVFip);
     230            0 :         m_imVectorSource.template       set_local_ips<refDim> (vSideLocSCVFipCoords, numSCVFip);
     231              :         
     232            0 :         m_imSource.template             set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     233            0 :         m_imReactionRate.template       set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     234            0 :         m_imReaction.template           set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     235            0 :         m_imReactionRateExpl.template   set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     236            0 :         m_imReactionExpl.template       set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     237            0 :         m_imSourceExpl.template         set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     238            0 :         m_imMassScale.template          set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     239            0 :         m_imMass.template                       set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     240              : 
     241            0 :         m_imOrthoDiffusion.template set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     242            0 :         m_imOrthoVelocity.template set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     243            0 :         m_imOrthoFlux.template set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     244            0 :         m_imOrthoVectorSource.template set_local_ips<refDim> (vSideLocSCVipCoords, numSCVip);
     245              :         
     246            0 :         m_imAperture.template           set_local_ips<dim> (&elemLocCOE, 1);
     247              :         
     248              : //      set global positions
     249              : 
     250            0 :         const position_type* vSCVFip = m_pFractGeo->scvf_global_ips ();
     251            0 :         m_imDiffusion.                  set_global_ips (vSCVFip, numSCVFip);
     252            0 :         m_imVelocity.                   set_global_ips (vSCVFip, numSCVFip);
     253            0 :         m_imFlux.                               set_global_ips (vSCVFip, numSCVFip);
     254            0 :         m_imVectorSource.               set_global_ips (vSCVFip, numSCVFip);
     255              :         
     256            0 :         const position_type* vSCVip = m_pFractGeo->scv_global_ips ();
     257            0 :         m_imSource.                             set_global_ips (vSCVip, numSCVip);
     258            0 :         m_imReactionRate.               set_global_ips (vSCVip, numSCVip);
     259            0 :         m_imReactionRateExpl.   set_global_ips (vSCVip, numSCVip);
     260            0 :         m_imReactionExpl.               set_global_ips (vSCVip, numSCVip);
     261            0 :         m_imSourceExpl.                 set_global_ips (vSCVip, numSCVip);
     262            0 :         m_imReaction.                   set_global_ips (vSCVip, numSCVip);
     263            0 :         m_imMassScale.                  set_global_ips (vSCVip, numSCVip);
     264            0 :         m_imMass.                               set_global_ips (vSCVip, numSCVip);
     265              : 
     266            0 :         const position_type* coe_global = m_pFractGeo->coe_global ();
     267            0 :         m_imAperture.set_global_ips (coe_global, 1);
     268              :         
     269              : //      init upwind for element type
     270            0 :         if(m_spConvShape.valid())
     271            0 :                 if(!m_spConvShape->template set_geometry_type<TFractFVGeom> (*m_pFractGeo))
     272            0 :                         UG_THROW("ConvectionDiffusionFractFV1::prep_elem:"
     273              :                                                         " Cannot init upwind for element type.");
     274            0 : }
     275              : 
     276              : /// computes the local stiffness matrix
     277              : template<typename TDomain>
     278              : template<typename TElem>
     279            0 : void ConvectionDiffusionFractFV1<TDomain>::add_jac_A_elem
     280              : (
     281              :         LocalMatrix & J, ///< the local matrix to update
     282              :         const LocalVector & u, ///< current approximation of the solution
     283              :         GridObject * elem, ///< grid element
     284              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     285              : )
     286              : {
     287              :         TElem * pElem = static_cast<TElem*> (elem);
     288              : 
     289            0 :         this->template fract_add_jac_A_elem<TElem> (J, u, pElem, vCornerCoords);
     290            0 :         this->template fract_bulk_add_jac_A_elem<TElem> (J, u, pElem, vCornerCoords);
     291            0 : }
     292              : 
     293              : /// assembles a singular source or sink in the jacobian
     294              : template<typename TDomain>
     295              : template<typename TElem>
     296              : void ConvectionDiffusionFractFV1<TDomain>::add_sss_jac_elem
     297              : (
     298              :         LocalMatrix& J, ///< the matrix to update
     299              :         const LocalVector& u, ///< current solution
     300              :         TElem* pElem, ///< the element
     301              :         size_t co, ///< corner for the source/sink
     302              :         number flux ///< flux through the source/sink (premultiplied by the length for lines)
     303              : )
     304              : {
     305            0 :         if (flux < 0.0)
     306              :                 // sink
     307            0 :                 J(_C_, co, _C_, co) -= flux;
     308              : }
     309              : 
     310              : /// computes the local stiffness matrix on a fracture element
     311              : template<typename TDomain>
     312              : template<typename TElem>
     313            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_add_jac_A_elem
     314              : (
     315              :         LocalMatrix & J, ///< the local matrix to update
     316              :         const LocalVector & u, ///< current approximation of the solution
     317              :         TElem * pElem, ///< grid element
     318              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     319              : )
     320              : {
     321            0 :         number half_fr_width = m_imAperture[0] / 2;
     322              :         
     323            0 :         const size_t numSh = m_pFractGeo->num_sh ();
     324              :         const size_t numScvf = m_pFractGeo->num_scvf ();
     325              :         
     326              : //      Diffusion and Velocity Term
     327            0 :         if (m_imDiffusion.data_given () || m_imVelocity.data_given ())
     328              :         {
     329              :         //      get conv shapes
     330            0 :                 const IConvectionShapes<dim>& convShape = get_updated_conv_shapes (false);
     331              :         
     332              :         //      loop Sub Control Volume Faces (SCVF)
     333            0 :                 for (size_t ip = 0; ip < numScvf; ++ip)
     334              :                 {
     335              :                 //      get current SCVF
     336            0 :                         const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
     337              : 
     338              :                 ////////////////////////////////////////////////////
     339              :                 // Diffusive Term
     340              :                 ////////////////////////////////////////////////////
     341            0 :                         if (m_imDiffusion.data_given ())
     342              :                         {
     343              :                         //      Diff. Tensor times Gradient
     344              :                                 MathVector<dim> Dgrad;
     345              :                                 
     346              :                         //      loop shape functions
     347            0 :                                 for (size_t sh = 0; sh < numSh; ++sh)
     348              :                                 {
     349              :                                 //      Compute Diffusion Tensor times Gradient
     350              :                                         MatVecMult (Dgrad, m_imDiffusion[ip], scvf.global_grad (sh));
     351              : 
     352              :                                 //      Compute flux at IP
     353            0 :                                         const number D_diff_flux = VecDot (Dgrad, scvf.normal ()) * half_fr_width;
     354              : 
     355            0 :                                         J(_C_, m_innerSideCo[scvf.from()], _C_, m_innerSideCo[sh]) -= D_diff_flux;
     356            0 :                                         J(_C_, m_innerSideCo[scvf.to()  ], _C_, m_innerSideCo[sh]) += D_diff_flux;
     357              :                                 }
     358              :                         }
     359              : 
     360              :                 ////////////////////////////////////////////////////
     361              :                 // Convective Term
     362              :                 ////////////////////////////////////////////////////
     363            0 :                         if (m_imVelocity.data_given ())
     364              :                         {
     365              :                         //      Add Flux contribution
     366            0 :                                 for (size_t sh = 0; sh < numSh; ++sh)
     367              :                                 {
     368            0 :                                         const number D_conv_flux = convShape (ip, sh) * half_fr_width;
     369              : 
     370              :                                 //      Add flux term to local matrix
     371            0 :                                         J(_C_, m_innerSideCo[scvf.from()], _C_, m_innerSideCo[sh]) += D_conv_flux;
     372            0 :                                         J(_C_, m_innerSideCo[scvf.to()  ], _C_, m_innerSideCo[sh]) -= D_conv_flux;
     373              :                                 }
     374              :                         }
     375              : 
     376              :                         // no explicit dependency on flux import
     377              :                 }
     378              :         }
     379              : 
     380              : //      Reaction rate
     381            0 :         if(m_imReactionRate.data_given())
     382              :         {
     383              :         //      loop Sub Control Volume (SCV)
     384            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     385              :                 {
     386              :                 //      get current SCV
     387              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     388              :                         
     389              :                 //      get associated node
     390            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     391              :                         
     392              :                 //      Add to local matrix
     393            0 :                         J(_C_, co, _C_, co) += m_imReactionRate[ip] * scv.volume () * half_fr_width;
     394              :                 }
     395              :         }
     396              :         
     397              : //      Reaction term does not explicitly depend on the associated unknown function
     398              : 
     399              : //      Assemble the singular sources and sinks
     400            0 :     if (m_sss_mngr.valid () && m_sss_mngr->num_lines () != 0)
     401              :     {
     402              :         typedef typename domain_type::position_accessor_type t_pos_accessor;
     403              :         typedef typename CDSingularSourcesAndSinks<dim>::template
     404              :                 line_iterator<side_type,t_pos_accessor,TFractFVGeom> t_lin_sss_iter;
     405              :         
     406            0 :                 t_pos_accessor& aaPos = this->domain()->position_accessor ();
     407            0 :                 Grid& grid = (Grid&) *this->domain()->grid ();
     408              :                 
     409            0 :                 for(size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
     410              :                 {
     411              :                 //      Get the corner of the face
     412              :                         size_t side_co = m_pFractGeo->scv(ip).node_id ();
     413              :                 //      Get associated node of the element (not side!)
     414            0 :                         size_t co = m_innerSideCo [m_pFractGeo->scv(ip).node_id ()];
     415              :                         
     416              :                 //      line sources (that correspond to the point sources)
     417            0 :                         for (t_lin_sss_iter line (m_sss_mngr.get (), m_innerFractSide, grid, aaPos, *m_pFractGeo, side_co);
     418            0 :                                 ! line.is_over (); ++line)
     419              :                         {
     420              :                                 FVLineSourceOrSink<dim, cd_line_sss_data<dim> > * line_sss = *line;
     421            0 :                                 if (! line_sss->marked_for (m_innerFractSide, side_co))
     422            0 :                                         continue;
     423              :                                 line_sss->compute (line.seg_start (), this->time (), -1); //TODO: set the subset id instead of -1
     424            0 :                                 add_sss_jac_elem (J, u, pElem, co, line_sss->flux () / 2);
     425              :                                 /* Remark: "/ 2" because the source is taken into account twice. */
     426              :                         }
     427              :                 }
     428              :         }
     429            0 : }
     430              : 
     431              : /// computes the local stiffness matrix of the fracture-bulk interaction terms on a fracture element
     432              : template<typename TDomain>
     433              : template<typename TElem>
     434            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_bulk_add_jac_A_elem
     435              : (
     436              :         LocalMatrix & J, ///< the local matrix to update
     437              :         const LocalVector & u, ///< current approximation of the solution
     438              :         TElem * pElem, ///< grid element
     439              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     440              : )
     441              : {
     442            0 :         number half_fr_width = m_imAperture[0] / 2;
     443              :         
     444              : //      loop over the corners of the inner side
     445            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
     446              :         {
     447              :         //      Get current SCV
     448              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
     449              :                 number s = scv.volume ();
     450              : 
     451              :         //      Get associated node of the element (not side!)
     452            0 :                 const int co = m_innerSideCo [scv.node_id()];
     453              :         
     454              :         //      Assemble Diffusion and Convection
     455              :                 number D_flux = 0, D_flux_fr = 0;
     456              :                 
     457            0 :                 if (m_imOrthoDiffusion.data_given ())
     458              :                 {
     459            0 :                         D_flux = m_imOrthoDiffusion[ip] / half_fr_width;
     460            0 :                         D_flux_fr = - D_flux;
     461              :                 }
     462              :         
     463            0 :         if (m_imOrthoVelocity.data_given ())
     464              :         {
     465              :                         /* We use the full upwind here: */
     466            0 :                         if (m_imOrthoVelocity[ip] >= 0)
     467            0 :                                 D_flux_fr -= m_imOrthoVelocity[ip];
     468              :                         else
     469            0 :                                 D_flux -= m_imOrthoVelocity[ip];
     470              :         }
     471              :                 
     472            0 :                 J(_C_, m_assCo [co], _C_, m_assCo [co]) += D_flux * s;
     473            0 :                 J(_C_, m_assCo [co], _C_, co          ) += D_flux_fr * s;
     474              :                 
     475            0 :                 J(_C_, co, _C_, m_assCo [co]) -= D_flux * s;
     476            0 :                 J(_C_, co, _C_, co          ) -= D_flux_fr * s;
     477              :         }
     478            0 : }
     479              : 
     480              : 
     481              : /// computes the mass matrix of a time-dependent problem
     482              : template<typename TDomain>
     483              : template<typename TElem>
     484            0 : void ConvectionDiffusionFractFV1<TDomain>::add_jac_M_elem
     485              : (
     486              :         LocalMatrix & J, ///< the local matrix to update
     487              :         const LocalVector & u, ///< current approximation of the solution
     488              :         GridObject * elem, ///< grid element
     489              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     490              : )
     491              : {
     492            0 :         if (!m_imMassScale.data_given ()) return;
     493              : 
     494            0 :         number half_fr_width = m_imAperture[0] / 2;
     495              :         
     496              : //      loop Sub Control Volumes (SCV)
     497            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     498              :         {
     499              :         //      get current SCV
     500              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     501              : 
     502              :         //      get associated node
     503            0 :                 const int co = m_innerSideCo [scv.node_id ()];
     504              : 
     505              :         //      Add to local matrix
     506            0 :                 J(_C_, co, _C_, co) += scv.volume() * m_imMassScale[ip] * half_fr_width;
     507              :         }
     508              : 
     509              : //      m_imMass part does not explicitly depend on associated unknown function
     510              : }
     511              :         
     512              : /// computes the stiffness part of the local defect
     513              : template<typename TDomain>
     514              : template<typename TElem>
     515            0 : void ConvectionDiffusionFractFV1<TDomain>::add_def_A_elem
     516              : (
     517              :         LocalVector & d, ///< the local defect to update
     518              :         const LocalVector & u, ///< current approximation of the solution
     519              :         GridObject * elem, ///< grid element
     520              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     521              : )
     522              : {
     523              :         TElem * pElem = static_cast<TElem*> (elem);
     524              : 
     525            0 :         this->template fract_add_def_A_elem<TElem> (d, u, pElem, vCornerCoords);
     526            0 :         this->template fract_bulk_add_def_A_elem<TElem> (d, u, pElem, vCornerCoords);
     527            0 : }
     528              : 
     529              : /// assembles a singular source or sink in the defect
     530              : template<typename TDomain>
     531              : template<typename TElem>
     532              : void ConvectionDiffusionFractFV1<TDomain>::add_sss_def_elem
     533              : (
     534              :         LocalVector& d, ///< the defect to update
     535              :         const LocalVector& u, ///< current solution
     536              :         TElem * pElem, ///< the element
     537              :         size_t co, ///< corner for the source/sink
     538              :         number flux ///< flux through the source/sink (premultiplied by the length for lines)
     539              : )
     540              : {
     541            0 :         if (flux > 0.0)
     542              :                 // source
     543            0 :                 d(_C_, co) -= flux;
     544              :         else
     545              :                 // sink
     546            0 :                 d(_C_, co) -= flux * u(_C_, co);
     547              : }
     548              : 
     549              : /// computes the stiffness part of the local defect on a fracture element
     550              : template<typename TDomain>
     551              : template<typename TElem>
     552            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_add_def_A_elem
     553              : (
     554              :         LocalVector & d, ///< the local defect to update
     555              :         const LocalVector & u, ///< current approximation of the solution
     556              :         TElem * pElem, ///< grid element
     557              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     558              : )
     559              : {
     560            0 :         number half_fr_width = m_imAperture[0] / 2;
     561              : 
     562              : //      Diff. Tensor times Gradient
     563              :         MathVector<dim> Dgrad;
     564              : 
     565            0 :     const size_t numSh = m_pFractGeo->num_sh ();
     566              :         const size_t numScvf = m_pFractGeo->num_scvf ();
     567              : 
     568              : //      Diffusion and Velocity Term
     569            0 :         if (m_imDiffusion.data_given () || m_imVelocity.data_given () || m_imFlux.data_given ())
     570              :         {
     571              :         //      get conv shapes
     572            0 :                 const IConvectionShapes<dim>& convShape = get_updated_conv_shapes (false);
     573              : 
     574              :         //      loop Sub Control Volume Faces (SCVF)
     575            0 :                 for(size_t ip = 0; ip < numScvf; ++ip)
     576              :                 {
     577              :                 //      get current SCVF
     578            0 :                         const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
     579              : 
     580              :                 ////////////////////////////////////////////////////
     581              :                 // Diffusive Term
     582              :                 ////////////////////////////////////////////////////
     583            0 :                         if(m_imDiffusion.data_given ())
     584              :                         {
     585              :                         //      to compute D \nabla c
     586              :                                 MathVector<dim> Dgrad_c, grad_c;
     587              : 
     588              :                         //      compute gradient and shape at ip
     589              :                                 VecSet (grad_c, 0.0);
     590            0 :                                 for(size_t sh = 0; sh < numSh; ++sh)
     591            0 :                                         VecScaleAppend (grad_c,
     592              :                                                 u (_C_, m_innerSideCo[sh]), scvf.global_grad (sh));
     593              : 
     594              :                         //      scale by diffusion tensor
     595              :                                 MatVecMult (Dgrad_c, m_imDiffusion[ip], grad_c);
     596              : 
     597              :                         //      Compute flux
     598            0 :                                 const number diff_flux = VecDot (Dgrad_c, scvf.normal ()) * half_fr_width;
     599              : 
     600              :                         //      Add to local defect
     601            0 :                                 d(_C_, m_innerSideCo [scvf.from()]) -= diff_flux;
     602            0 :                                 d(_C_, m_innerSideCo [scvf.to()  ]) += diff_flux;
     603              :                         }
     604              : 
     605              :                 ////////////////////////////////////////////////////
     606              :                 // Convective Term
     607              :                 ////////////////////////////////////////////////////
     608            0 :                         if(m_imVelocity.data_given())
     609              :                         {
     610              :                         //      sum up convective flux using convection shapes
     611              :                                 number conv_flux = 0.0;
     612            0 :                                 for(size_t sh = 0; sh < numSh; ++sh)
     613            0 :                                         conv_flux += u (_C_, m_innerSideCo[sh]) * convShape (ip, sh);
     614            0 :                                 conv_flux *= half_fr_width;
     615              : 
     616              :                         //  add to local defect
     617            0 :                                 d(_C_, m_innerSideCo [scvf.from()]) += conv_flux;
     618            0 :                                 d(_C_, m_innerSideCo [scvf.to()  ]) -= conv_flux;
     619              :                         }
     620              : 
     621              :                 /////////////////////////////////////////////////////
     622              :                 // Flux Term
     623              :                 /////////////////////////////////////////////////////
     624            0 :                         if(m_imFlux.data_given())
     625              :                         {
     626              :                         //      sum up flux
     627            0 :                                 const number flux = VecDot (m_imFlux[ip], scvf.normal ()) * half_fr_width;
     628              : 
     629              :                         //  add to local defect
     630            0 :                                 d(_C_, m_innerSideCo [scvf.from()]) += flux;
     631            0 :                                 d(_C_, m_innerSideCo [scvf.to()  ]) -= flux;
     632              :                         }
     633              :                 }
     634              :         }
     635              : 
     636              : //      Reaction rate
     637            0 :         if (m_imReactionRate.data_given ())
     638              :         {
     639              :         //      loop Sub Control Volumes (SCV)
     640            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     641              :                 {
     642              :                 //      get current SCV
     643              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     644              : 
     645              :                 //      get associated node
     646            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     647              : 
     648              :                 //      Add to local defect
     649            0 :                         d(_C_, co) += u(_C_, co) * m_imReactionRate[ip] * scv.volume () * half_fr_width;
     650              :                 }
     651              :         }
     652              : 
     653              : //      Reaction term
     654            0 :         if (m_imReaction.data_given ())
     655              :         {
     656              :         //      loop Sub Control Volumes (SCV)
     657            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     658              :                 {
     659              :                 //      get current SCV
     660              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     661              : 
     662              :                 //      get associated node
     663            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     664              : 
     665              :                 //      Add to local defect
     666            0 :                         d(_C_, co) += m_imReaction[ip] * scv.volume () * half_fr_width;
     667              :                 }
     668              :         }
     669              : 
     670              : //      Assemble the singular sources and sinks
     671            0 :     if (m_sss_mngr.valid () && m_sss_mngr->num_lines () != 0)
     672              :     {
     673              :         typedef typename domain_type::position_accessor_type t_pos_accessor;
     674              :         typedef typename CDSingularSourcesAndSinks<dim>::template
     675              :                 line_iterator<side_type,t_pos_accessor,TFractFVGeom> t_lin_sss_iter;
     676              :         
     677            0 :                 t_pos_accessor& aaPos = this->domain()->position_accessor ();
     678            0 :                 Grid& grid = (Grid&) *this->domain()->grid ();
     679              :                 
     680            0 :                 for(size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
     681              :                 {
     682              :                 //      Get the corner of the face
     683              :                         size_t side_co = m_pFractGeo->scv(ip).node_id ();
     684              :                 //      Get associated node of the element (not side!)
     685            0 :                         size_t co = m_innerSideCo [m_pFractGeo->scv(ip).node_id ()];
     686              :                         
     687              :                 //      line sources (that correspond to the point sources)
     688            0 :                         for (t_lin_sss_iter line (m_sss_mngr.get (), m_innerFractSide, grid, aaPos, *m_pFractGeo, side_co);
     689            0 :                                 ! line.is_over (); ++line)
     690              :                         {
     691              :                                 FVLineSourceOrSink<dim, cd_line_sss_data<dim> > * line_sss = *line;
     692            0 :                                 if (! line_sss->marked_for (m_innerFractSide, side_co))
     693            0 :                                         continue;
     694              :                                 line_sss->compute (line.seg_start (), this->time (), -1); //TODO: set the subset id instead of -1
     695            0 :                                 add_sss_def_elem (d, u, pElem, co, line_sss->flux () / 2);
     696              :                                 /* Remark: "/ 2" because the source is taken into account twice. */
     697              :                         }
     698              :                 }
     699              :         }
     700            0 : }
     701              : 
     702              : /// computes the stiffness fracture-bulk interaction terms of the local defect on a fracture element
     703              : template<typename TDomain>
     704              : template<typename TElem>
     705            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_bulk_add_def_A_elem
     706              : (
     707              :         LocalVector & d, ///< the local defect to update
     708              :         const LocalVector & u, ///< current approximation of the solution
     709              :         TElem * pElem, ///< grid element
     710              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     711              : )
     712              : {
     713              :         number orthC_f, orthC_m;
     714              :         
     715            0 :         number half_fr_width = m_imAperture[0] / 2;
     716              :         
     717              : //      loop over the corners of the inner side
     718            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
     719              :         {
     720              :         //      Get current SCV
     721              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
     722              : 
     723              :         //      Get associated node of the element (not side!)
     724            0 :                 const int co = m_innerSideCo [scv.node_id()];
     725              :                 
     726              :         //      Get the corner values
     727            0 :                 orthC_f = u(_C_, co);
     728            0 :                 orthC_m = u(_C_, m_assCo[co]);
     729              :         
     730              :         //      Assemble Diffusion, Convection and the Flux
     731              :         number flux = 0;
     732              :                 
     733            0 :         if (m_imOrthoDiffusion.data_given ())
     734            0 :                 flux = m_imOrthoDiffusion[ip] * (orthC_m - orthC_f) / half_fr_width;
     735              :         
     736            0 :         if (m_imOrthoVelocity.data_given ())
     737              :         {
     738            0 :                         number orthVelocity = m_imOrthoVelocity[ip];
     739              :                         /* We use the full upwind here: */
     740            0 :                         flux -= orthVelocity * ((orthVelocity >= 0)? orthC_f : orthC_m);
     741              :                 }
     742              :         
     743            0 :                 if (m_imOrthoFlux.data_given ())
     744            0 :                         flux -= m_imOrthoFlux[ip];
     745              :         
     746            0 :         flux *= scv.volume ();
     747            0 :         d(_C_, m_assCo[co]) += flux;
     748            0 :         d(_C_, co) -= flux;
     749              :         }
     750            0 : }
     751              : 
     752              : /// computes the stiffness part of the local defect
     753              : template<typename TDomain>
     754              : template<typename TElem>
     755            0 : void ConvectionDiffusionFractFV1<TDomain>::add_def_A_expl_elem
     756              : (
     757              :         LocalVector & d, ///< the local defect to update
     758              :         const LocalVector & u, ///< current approximation of the solution
     759              :         GridObject * elem, ///< grid element
     760              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     761              : )
     762              : {
     763              :         TElem * pElem = static_cast<TElem*> (elem);
     764              : 
     765            0 :         this->template fract_add_def_A_expl_elem<TElem> (d, u, pElem, vCornerCoords);
     766              :         this->template fract_bulk_add_def_A_expl_elem<TElem> (d, u, pElem, vCornerCoords);
     767            0 : }
     768              : 
     769              : /// computes the stiffness part of the local defect on a fracture element
     770              : template<typename TDomain>
     771              : template<typename TElem>
     772            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_add_def_A_expl_elem
     773              : (
     774              :         LocalVector & d, ///< the local defect to update
     775              :         const LocalVector & u, ///< current approximation of the solution
     776              :         TElem * pElem, ///< grid element
     777              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     778              : )
     779              : {
     780            0 :         number half_fr_width = m_imAperture[0] / 2;
     781              : 
     782              : //      Reaction rate
     783            0 :         if (m_imReactionRateExpl.data_given ())
     784              :         {
     785              :         //      loop Sub Control Volumes (SCV)
     786            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     787              :                 {
     788              :                 //      get current SCV
     789              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     790              : 
     791              :                 //      get associated node
     792            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     793              : 
     794              :                 //      Add to local defect
     795            0 :                         d(_C_, co) += u(_C_, co) * m_imReactionRateExpl[ip] * scv.volume () * half_fr_width;
     796              :                 }
     797              :         }
     798              : 
     799              : //      reaction
     800            0 :         if (m_imReactionExpl.data_given ())
     801              :         {
     802              :         //      loop Sub Control Volumes (SCV)
     803            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     804              :                 {
     805              :                 //      get current SCV
     806              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     807              : 
     808              :                 //      get associated node
     809            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     810              : 
     811              :                 //      Add to local defect
     812            0 :                         d(_C_, co) += m_imReactionExpl[ip] * scv.volume () * half_fr_width;
     813              :                 }
     814              :         }
     815              : 
     816              : //      source
     817            0 :         if (m_imSourceExpl.data_given ())
     818              :         {
     819              :                 //      loop Sub Control Volumes (SCV)
     820            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     821              :                 {
     822              :                         //      get current SCV
     823              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     824              : 
     825              :                         //      get associated node
     826            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     827              : 
     828              :                         //      Add to local rhs
     829            0 :                         d(_C_, co) -= m_imSourceExpl[ip] * scv.volume () * half_fr_width;
     830              :                 }
     831              :         }
     832            0 : }
     833              : 
     834              : /// computes the stiffness fracture-bulk interaction terms of the local defect on a fracture element
     835              : template<typename TDomain>
     836              : template<typename TElem>
     837              : void ConvectionDiffusionFractFV1<TDomain>::fract_bulk_add_def_A_expl_elem
     838              : (
     839              :         LocalVector & d, ///< the local defect to update
     840              :         const LocalVector & u, ///< current approximation of the solution
     841              :         TElem * pElem, ///< grid element
     842              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     843              : )
     844              : {
     845              : }
     846              : 
     847              : /// computes the mass part of the defect of a time-dependent problem
     848              : template<typename TDomain>
     849              : template<typename TElem>
     850            0 : void ConvectionDiffusionFractFV1<TDomain>::add_def_M_elem
     851              : (
     852              :         LocalVector & d, ///< the local defect to update
     853              :         const LocalVector & u, ///< current approximation of the solution
     854              :         GridObject * elem, ///< grid element
     855              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     856              : )
     857              : {
     858            0 :         if (!m_imMassScale.data_given () && !m_imMass.data_given ()) return;
     859              : 
     860            0 :         number half_fr_width = m_imAperture[0] / 2;
     861              :         
     862              : //      loop Sub Control Volumes (SCV)
     863            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     864              :         {
     865              :         //      get current SCV
     866              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     867              : 
     868              :         //      get associated node
     869            0 :                 const int co = m_innerSideCo [scv.node_id ()];
     870              : 
     871              :         //      mass value
     872              :                 number val = 0;
     873              : 
     874              :         //      multiply by scaling
     875            0 :                 if (m_imMassScale.data_given ())
     876            0 :                         val += m_imMassScale[ip] * u(_C_, co);
     877              : 
     878              :         //      add mass
     879            0 :                 if (m_imMass.data_given ())
     880            0 :                         val += m_imMass[ip];
     881              : 
     882              :         //      Add to local defect
     883            0 :                 d(_C_, co) += val * scv.volume () * half_fr_width;
     884              :         }
     885              : }
     886              : 
     887              : /// computes the right-hand side due to the sources
     888              : template<typename TDomain>
     889              : template<typename TElem>
     890            0 : void ConvectionDiffusionFractFV1<TDomain>::add_rhs_elem
     891              : (
     892              :         LocalVector & d, ///< the right-hand side to update
     893              :         GridObject * elem, ///< grid element
     894              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     895              : )
     896              : {
     897              :         TElem * pElem = static_cast<TElem*> (elem);
     898              : 
     899            0 :         this->template fract_add_rhs_elem<TElem> (d, pElem, vCornerCoords);
     900            0 :         this->template fract_bulk_add_rhs_elem<TElem> (d, pElem, vCornerCoords);
     901            0 : }
     902              : 
     903              : /// computes the right-hand side due to the sources on a fracture element
     904              : template<typename TDomain>
     905              : template<typename TElem>
     906            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_add_rhs_elem
     907              : (
     908              :         LocalVector & d, ///< the local defect to update
     909              :         TElem * pElem, ///< grid element
     910              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     911              : )
     912              : {
     913            0 :         number half_fr_width = m_imAperture[0] / 2;
     914              : 
     915            0 :         if (m_imSource.data_given ())
     916              :                 // loop Sub Control Volumes (SCV)
     917            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
     918              :                 {
     919              :                         // get current SCV
     920              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
     921              : 
     922              :                         // get associated node
     923            0 :                         const int co = m_innerSideCo [scv.node_id ()];
     924              : 
     925              :                         // Add to local rhs
     926            0 :                         d(_C_, co) += m_imSource[ip] * scv.volume () * half_fr_width;
     927              :                 }
     928              : 
     929            0 :         if (m_imVectorSource.data_given ())
     930              :                 // loop Sub Control Volume Fraces (SCVF)
     931            0 :                 for(size_t ip = 0; ip < m_pFractGeo->num_scvf (); ++ip)
     932              :                 {
     933              :                         // get current SCVF
     934              :                         const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
     935              :                         
     936              :                         // compute the flux
     937            0 :                         number flux = VecDot (m_imVectorSource[ip], scvf.normal ()) * half_fr_width;
     938              : 
     939              :                         // Add to local rhs
     940            0 :                         d(_C_, m_innerSideCo [scvf.from()]) -= flux;
     941            0 :                         d(_C_, m_innerSideCo [scvf.to()  ]) += flux;
     942              :                 }
     943            0 : }
     944              : 
     945              : /// computes the fracture-bulk interaction terms of the local rhs on a fracture element
     946              : template<typename TDomain>
     947              : template<typename TElem>
     948            0 : void ConvectionDiffusionFractFV1<TDomain>::fract_bulk_add_rhs_elem
     949              : (
     950              :         LocalVector & d, ///< the local defect to update
     951              :         TElem * pElem, ///< grid element
     952              :         const position_type vCornerCoords [] ///< corner coordinates of the grid element
     953              : )
     954              : {
     955            0 :         if (m_imOrthoVectorSource.data_given ())
     956              :                 // loop Sub Control Volumes (SCV)
     957            0 :                 for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
     958              :                 {
     959              :                 //      Get current SCV
     960              :                         const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
     961              : 
     962              :                 //      Get associated node of the element (not side!)
     963            0 :                         const int co = m_innerSideCo [scv.node_id()];
     964              :                 
     965            0 :                         number flux = m_imOrthoVectorSource[ip] * scv.volume ();
     966            0 :                         d(_C_, m_assCo[co]) += flux;
     967            0 :                         d(_C_, co) -= flux;
     968              :                 }
     969            0 : }       
     970              : 
     971              : ///     computes the linearized defect w.r.t to the fracture velocity
     972              : template<typename TDomain>
     973              : template<typename TElem>
     974            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_velocity
     975              : (
     976              :         const LocalVector& u,
     977              :         std::vector<std::vector<MathVector<dim> > > vvvLinDef[],
     978              :         const size_t nip
     979              : )
     980              : {
     981              : //      reset the values for the linearized defect
     982            0 :         for(size_t ip = 0; ip < nip; ++ip)
     983            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
     984            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
     985              :                                 vvvLinDef[ip][c][sh] = 0.0;
     986              : 
     987              : //      get conv shapes
     988            0 :         const IConvectionShapes<dim>& convShape = get_updated_conv_shapes (true);
     989              : 
     990              : //  loop Sub Control Volume Faces (SCVF)
     991            0 :         for(size_t ip = 0; ip < m_pFractGeo->num_scvf (); ++ip)
     992              :         {
     993              :         // get current SCVF
     994              :                 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
     995              : 
     996              :         //      sum up contributions of convection shapes
     997              :                 MathVector<dim> linDefect;
     998              :                 VecSet(linDefect, 0.0);
     999            0 :                 for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
    1000            0 :                         VecScaleAppend (linDefect, u (_C_, m_innerSideCo[sh]), convShape.D_vel (ip, sh));
    1001              : 
    1002              :         //      add parts for both sides of scvf
    1003            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.from()]] += linDefect;
    1004            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.to()]  ] -= linDefect;
    1005              :         }
    1006            0 : }
    1007              : 
    1008              : ///     computes the linearized defect w.r.t to the orthogonal velocity
    1009              : template<typename TDomain>
    1010              : template<typename TElem>
    1011            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_ortho_velocity
    1012              : (
    1013              :         const LocalVector& u,
    1014              :         std::vector<std::vector<number> > vvvLinDef[],
    1015              :         const size_t nip
    1016              : )
    1017              : {
    1018              : //      reset the values for the linearized defect
    1019            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1020            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1021            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1022            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1023              : 
    1024            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1025              :         {
    1026              :         //      Get current SCV
    1027              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1028              : 
    1029              :         //      Get associated node of the element (not side!)
    1030            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1031              :                 
    1032              :         //      Get the corner values
    1033            0 :                 number orthC_f = u(_C_, co);
    1034            0 :                 number orthC_m = u(_C_, m_assCo[co]);
    1035              :         
    1036              :         //      Compute the derivative of the flux
    1037            0 :                 number D_flux_vel = - ((m_imOrthoVelocity[ip] >= 0)? orthC_f : orthC_m) * scv.volume ();
    1038              : 
    1039              :         //      add parts for both sides of the fracture
    1040            0 :                 vvvLinDef[ip][_C_][m_assCo[co]] += D_flux_vel;
    1041            0 :                 vvvLinDef[ip][_C_][co         ] -= D_flux_vel;
    1042              :         }
    1043            0 : }
    1044              : 
    1045              : ///     computes the linearized defect w.r.t to the fracture diffusion
    1046              : template<typename TDomain>
    1047              : template<typename TElem>
    1048            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_diffusion
    1049              : (
    1050              :         const LocalVector& u,
    1051              :         std::vector<std::vector<MathMatrix<dim,dim> > > vvvLinDef[],
    1052              :         const size_t nip
    1053              : )
    1054              : {
    1055              : //      reset the values for the linearized defect
    1056            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1057            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1058            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1059              :                                 vvvLinDef[ip][c][sh] = 0.0;
    1060              : 
    1061              : //      get conv shapes
    1062            0 :         const IConvectionShapes<dim>& convShape = get_updated_conv_shapes (true);
    1063              : 
    1064              : //  loop Sub Control Volume Faces (SCVF)
    1065            0 :         for(size_t ip = 0; ip < m_pFractGeo->num_scvf (); ++ip)
    1066              :         {
    1067              :         // get current SCVF
    1068              :                 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
    1069              : 
    1070              :         //      compute gradient at ip
    1071              :                 MathVector<dim> grad_c;
    1072              :                 VecSet (grad_c, 0.0);
    1073            0 :                 for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
    1074            0 :                         VecScaleAppend (grad_c, u (_C_, m_innerSideCo[sh]), scvf.global_grad (sh));
    1075              : 
    1076              :         //      compute the lin defect at this ip
    1077              :                 MathMatrix<dim,dim> linDefect;
    1078              : 
    1079              :         //      part coming from $-\nabla u * \vec{n}
    1080            0 :                 for(size_t k=0; k < (size_t) dim; ++k)
    1081            0 :                         for(size_t j = 0; j < (size_t)dim; ++j)
    1082            0 :                                 linDefect(j,k) = (scvf.normal())[j] * grad_c[k];
    1083              : 
    1084              :         //      add contribution from convection shapes
    1085            0 :                 if(convShape.non_zero_deriv_diffusion ())
    1086            0 :                         for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
    1087            0 :                                 MatAdd (linDefect,
    1088              :                                         convShape.D_diffusion (ip, sh), u (_C_, m_innerSideCo[sh]));
    1089              : 
    1090              :         //      add contributions
    1091            0 :                 vvvLinDef[ip][_C_][m_innerSideCo[scvf.from()]] -= linDefect;
    1092            0 :                 vvvLinDef[ip][_C_][m_innerSideCo[scvf.to()]  ] += linDefect;
    1093              :         }
    1094            0 : }
    1095              : 
    1096              : ///     computes the linearized defect w.r.t to the orthogonal diffusion
    1097              : template<typename TDomain>
    1098              : template<typename TElem>
    1099            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_ortho_diffusion
    1100              : (
    1101              :         const LocalVector& u,
    1102              :         std::vector<std::vector<number> > vvvLinDef[],
    1103              :         const size_t nip
    1104              : )
    1105              : {
    1106              : //      reset the values for the linearized defect
    1107            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1108            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1109            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1110            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1111              : 
    1112              :         number orthC_f, orthC_m;
    1113              :         
    1114            0 :         number half_fr_width = m_imAperture[0] / 2;
    1115              :         
    1116              : //      loop over the corners of the inner side
    1117            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1118              :         {
    1119              :         //      Get current SCV
    1120              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1121              : 
    1122              :         //      Get associated node of the element (not side!)
    1123            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1124              :                 
    1125              :         //      Get the corner values
    1126            0 :                 orthC_f = u(_C_, co);
    1127            0 :                 orthC_m = u(_C_, m_assCo[co]);
    1128              :         
    1129            0 :                 number linDefect = (orthC_m - orthC_f) * scv.volume () / half_fr_width;
    1130              : 
    1131              :         //      add contributions
    1132            0 :                 vvvLinDef[ip][_C_][m_assCo[co]] += linDefect;
    1133            0 :                 vvvLinDef[ip][_C_][co         ] -= linDefect;
    1134              :     }
    1135            0 : }
    1136              : 
    1137              : ///     computes the linearized defect w.r.t to the fracture flux
    1138              : template<typename TDomain>
    1139              : template<typename TElem>
    1140            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_flux
    1141              : (
    1142              :         const LocalVector& u,
    1143              :         std::vector<std::vector<MathVector<dim> > > vvvLinDef[],
    1144              :         const size_t nip
    1145              : )
    1146              : {
    1147              : //      reset the values for the linearized defect
    1148            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1149            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1150            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1151              :                                 vvvLinDef[ip][c][sh] = 0.0;
    1152              : 
    1153              : //  loop Sub Control Volume Faces (SCVF)
    1154            0 :         for(size_t ip = 0; ip < m_pFractGeo->num_scvf(); ++ip)
    1155              :         {
    1156              :         // get current SCVF
    1157              :                 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
    1158              : 
    1159              :         //      add parts for both sides of scvf
    1160            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.from()]] += scvf.normal();
    1161            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.to()  ]] -= scvf.normal();
    1162              :         }
    1163            0 : }
    1164              : 
    1165              : ///     computes the linearized defect w.r.t to the orthogonal flux
    1166              : template<typename TDomain>
    1167              : template<typename TElem>
    1168            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_ortho_flux
    1169              : (
    1170              :         const LocalVector& u,
    1171              :         std::vector<std::vector<number> > vvvLinDef[],
    1172              :         const size_t nip
    1173              : )
    1174              : {
    1175              : //      reset the values for the linearized defect
    1176            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1177            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1178            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1179            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1180              : 
    1181              : //      loop over the corners of the inner side
    1182            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1183              :         {
    1184              :         //      Get current SCV
    1185              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1186              :         
    1187              :         //      Get associated node of the element (not side!)
    1188            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1189              :                 
    1190              :         //      add parts for both sides of the fracture
    1191            0 :                 vvvLinDef[ip][_C_][m_assCo[co]] += scv.volume ();
    1192            0 :                 vvvLinDef[ip][_C_][co         ] -= scv.volume ();
    1193              :         }
    1194            0 : }
    1195              : 
    1196              : ///     computes the linearized defect w.r.t to the reaction source
    1197              : template<typename TDomain>
    1198              : template<typename TElem>
    1199            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_reaction
    1200              : (
    1201              :         const LocalVector& u,
    1202              :         std::vector<std::vector<number> > vvvLinDef[],
    1203              :         const size_t nip
    1204              : )
    1205              : {
    1206              : //      reset the values for the linearized defect
    1207            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1208            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1209            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1210            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1211              : 
    1212            0 :         number half_fr_width = m_imAperture[0] / 2;
    1213              :         
    1214              : //      loop over the corners of the inner side
    1215            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1216              :         {
    1217              :         //      Get current SCV
    1218              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1219              :         
    1220              :         //      Get associated node of the element (not side!)
    1221            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1222              :                 
    1223              :         //      add parts for both sides of the fracture
    1224            0 :                 vvvLinDef[ip][_C_][co] = scv.volume () * half_fr_width;
    1225              :         }
    1226            0 : }
    1227              : 
    1228              : ///     computes the linearized defect w.r.t to the reaction rate
    1229              : template<typename TDomain>
    1230              : template<typename TElem>
    1231            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_reaction_rate
    1232              : (
    1233              :         const LocalVector& u,
    1234              :         std::vector<std::vector<number> > vvvLinDef[],
    1235              :         const size_t nip
    1236              : )
    1237              : {
    1238              : //      reset the values for the linearized defect
    1239            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1240            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1241            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1242            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1243              : 
    1244            0 :         number half_fr_width = m_imAperture[0] / 2;
    1245              :         
    1246              : //      loop over the corners of the inner side
    1247            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1248              :         {
    1249              :         //      Get current SCV
    1250              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1251              :         
    1252              :         //      Get associated node of the element (not side!)
    1253            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1254              :                 
    1255              :         //      add parts for both sides of the fracture
    1256            0 :                 vvvLinDef[ip][_C_][co] = u(_C_, co) * scv.volume () * half_fr_width;
    1257              :         }
    1258            0 : }
    1259              : 
    1260              : ///     computes the linearized defect w.r.t to the source
    1261              : template<typename TDomain>
    1262              : template<typename TElem>
    1263            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_source
    1264              : (
    1265              :         const LocalVector& u,
    1266              :         std::vector<std::vector<number> > vvvLinDef[],
    1267              :         const size_t nip
    1268              : )
    1269              : {
    1270              : //      reset the values for the linearized defect
    1271            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1272            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1273            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1274            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1275              : 
    1276            0 :         number half_fr_width = m_imAperture[0] / 2;
    1277              :         
    1278              : //      loop over the corners of the inner side
    1279            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1280              :         {
    1281              :         //      Get current SCV
    1282              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1283              :         
    1284              :         //      Get associated node of the element (not side!)
    1285            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1286              :                 
    1287              :         //      add parts for both sides of the fracture
    1288            0 :                 vvvLinDef[ip][_C_][co] = scv.volume () * half_fr_width;
    1289              :         }
    1290            0 : }
    1291              : 
    1292              : ///     computes the linearized defect w.r.t to the fracture flux
    1293              : template<typename TDomain>
    1294              : template<typename TElem>
    1295            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_vector_source
    1296              : (
    1297              :         const LocalVector& u,
    1298              :         std::vector<std::vector<MathVector<dim> > > vvvLinDef[],
    1299              :         const size_t nip
    1300              : )
    1301              : {
    1302              : //      reset the values for the linearized defect
    1303            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1304            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1305            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1306              :                                 vvvLinDef[ip][c][sh] = 0.0;
    1307              : 
    1308              : //  loop Sub Control Volume Faces (SCVF)
    1309            0 :         for(size_t ip = 0; ip < m_pFractGeo->num_scvf(); ++ip)
    1310              :         {
    1311              :         // get current SCVF
    1312              :                 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf (ip);
    1313              : 
    1314              :         //      add parts for both sides of scvf
    1315            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.from()]] -= scvf.normal();
    1316            0 :                 vvvLinDef[ip][_C_][m_innerSideCo [scvf.to()  ]] += scvf.normal();
    1317              :         }
    1318            0 : }
    1319              : 
    1320              : ///     computes the linearized defect w.r.t to the orthogonal flux
    1321              : template<typename TDomain>
    1322              : template<typename TElem>
    1323            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_ortho_vector_source
    1324              : (
    1325              :         const LocalVector& u,
    1326              :         std::vector<std::vector<number> > vvvLinDef[],
    1327              :         const size_t nip
    1328              : )
    1329              : {
    1330              : //      reset the values for the linearized defect
    1331            0 :         for(size_t ip = 0; ip < nip; ++ip)
    1332            0 :                 for(size_t c = 0; c < vvvLinDef[ip].size(); ++c)
    1333            0 :                         for(size_t sh = 0; sh < vvvLinDef[ip][c].size(); ++sh)
    1334            0 :                                 vvvLinDef[ip][c][sh] = 0.0;
    1335              : 
    1336              : //      loop over the corners of the inner side
    1337            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
    1338              :         {
    1339              :         //      Get current SCV
    1340              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
    1341              :         
    1342              :         //      Get associated node of the element (not side!)
    1343            0 :                 const int co = m_innerSideCo [scv.node_id()];
    1344              :                 
    1345              :         //      add parts for both sides of the fracture
    1346            0 :                 vvvLinDef[ip][_C_][m_assCo[co]] -= scv.volume ();
    1347            0 :                 vvvLinDef[ip][_C_][co         ] += scv.volume ();
    1348              :         }
    1349            0 : }
    1350              : 
    1351              : //      computes the linearized defect w.r.t to the mass scale
    1352              : template<typename TDomain>
    1353              : template <typename TElem>
    1354            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_mass_scale
    1355              : (
    1356              :         const LocalVector& u,
    1357              :         std::vector<std::vector<number> > vvvLinDef[],
    1358              :         const size_t nip
    1359              : )
    1360              : {
    1361            0 :         number half_fr_width = m_imAperture[0] / 2;
    1362              :         
    1363              : //      loop Sub Control Volumes (SCV)
    1364            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
    1365              :         {
    1366              :         //      get current SCV
    1367              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
    1368              : 
    1369              :         //      get associated node
    1370            0 :                 const int co = m_innerSideCo [scv.node_id ()];
    1371              : 
    1372              :         //      set lin defect
    1373            0 :                 vvvLinDef[co][_C_][co] = u(_C_, co) * scv.volume () * half_fr_width;
    1374              :         }
    1375            0 : }
    1376              : 
    1377              : //      computes the linearized defect w.r.t to the mass scale
    1378              : template<typename TDomain>
    1379              : template <typename TElem>
    1380            0 : void ConvectionDiffusionFractFV1<TDomain>::lin_def_mass
    1381              : (
    1382              :         const LocalVector& u,
    1383              :         std::vector<std::vector<number> > vvvLinDef[],
    1384              :         const size_t nip
    1385              : )
    1386              : {
    1387            0 :         number half_fr_width = m_imAperture[0] / 2;
    1388              : 
    1389              : //      loop Sub Control Volumes (SCV)
    1390            0 :         for (size_t ip = 0; ip < m_pFractGeo->num_scv(); ++ip)
    1391              :         {
    1392              :         //      get current SCV
    1393              :                 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv (ip);
    1394              : 
    1395              :         //      get associated node
    1396            0 :                 const int co = m_innerSideCo [scv.node_id ()];
    1397              : 
    1398              :         //      set lin defect
    1399            0 :                 vvvLinDef[co][_C_][co] = scv.volume () * half_fr_width;
    1400              :         }
    1401            0 : }
    1402              : 
    1403              : /// registers the local assembler functions for a given element
    1404              : template<typename TDomain>
    1405              : template<typename TElem>
    1406            0 : void ConvectionDiffusionFractFV1<TDomain>::register_func ()
    1407              : {
    1408              :         ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1409              :         typedef this_type T;
    1410              : 
    1411              :         this->clear_add_fct(id);
    1412              :         
    1413              :         this->set_prep_elem_loop_fct (id, &T::template prep_elem_loop<TElem>);
    1414              :         this->set_prep_elem_fct (     id, &T::template prep_elem<TElem>);
    1415              :         this->set_fsh_elem_loop_fct ( id, &T::template fsh_elem_loop<TElem>);
    1416              :         this->set_add_jac_A_elem_fct (id, &T::template add_jac_A_elem<TElem>);
    1417              :         this->set_add_jac_M_elem_fct (id, &T::template add_jac_M_elem<TElem>);
    1418              :         this->set_add_def_A_elem_fct (id, &T::template add_def_A_elem<TElem>);
    1419              :         this->set_add_def_A_expl_elem_fct(id, &T::template add_def_A_expl_elem<TElem>);
    1420              :         this->set_add_def_M_elem_fct (id, &T::template add_def_M_elem<TElem>);
    1421              :         this->set_add_rhs_elem_fct (  id, &T::template add_rhs_elem<TElem>);
    1422              : 
    1423              : //      set computation of linearized defect w.r.t velocity, diffusion etc.
    1424            0 :         m_imDiffusion.set_fct (id, this, &T::template lin_def_diffusion<TElem>);
    1425            0 :         m_imOrthoDiffusion.set_fct (id, this, &T::template lin_def_ortho_diffusion<TElem>);
    1426            0 :         m_imVelocity.set_fct (id, this, &T::template lin_def_velocity<TElem>);
    1427            0 :         m_imOrthoVelocity.set_fct (id, this, &T::template lin_def_ortho_velocity<TElem>);
    1428            0 :         m_imFlux.set_fct (id, this, &T::template lin_def_flux<TElem>);
    1429            0 :         m_imOrthoFlux.set_fct (id, this, &T::template lin_def_ortho_flux<TElem>);
    1430            0 :         m_imReactionRate.set_fct (id, this, &T::template lin_def_reaction_rate<TElem>);
    1431            0 :         m_imReaction.set_fct (id, this, &T::template lin_def_reaction<TElem>);
    1432            0 :         m_imSource.set_fct (id, this, &T::template lin_def_source<TElem>);
    1433            0 :         m_imVectorSource.set_fct (id, this, &T::template lin_def_vector_source<TElem>);
    1434            0 :         m_imOrthoVectorSource.set_fct (id, this, &T::template lin_def_ortho_vector_source<TElem>);
    1435            0 :         m_imMassScale.set_fct (id, this, &T::template lin_def_mass_scale<TElem>);
    1436            0 :         m_imMass.set_fct (id, this, &T::template lin_def_mass<TElem>);
    1437            0 : }
    1438              : 
    1439              : ///     registers the interface functions for all types of the elements
    1440              : template<typename TDomain>
    1441            0 : void ConvectionDiffusionFractFV1<TDomain>::register_all_funcs ()
    1442              : {
    1443              :         typedef typename domain_traits<dim>::DimElemList AssembleElemList;
    1444              :         
    1445            0 :         boost::mpl::for_each<AssembleElemList> (RegisterLocalDiscr (this));
    1446            0 : }
    1447              : 
    1448              : ////////////////////////////////////////////////////////////////////////////////
    1449              : //      explicit template instantiations
    1450              : ////////////////////////////////////////////////////////////////////////////////
    1451              : 
    1452              : #ifdef UG_DIM_2
    1453              : template class ConvectionDiffusionFractFV1<Domain2d>;
    1454              : #endif
    1455              : #ifdef UG_DIM_3
    1456              : template class ConvectionDiffusionFractFV1<Domain3d>;
    1457              : #endif
    1458              : 
    1459              : } // end namespace ConvectionDiffusionPlugin
    1460              : } // namespace ug
    1461              : 
    1462              : /* End of File */
        

Generated by: LCOV version 2.0-1