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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_USER_DATA__
      34              : #define __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_USER_DATA__
      35              : 
      36              : #include "common/common.h"
      37              : 
      38              : #include "lib_grid/tools/subset_group.h"
      39              : 
      40              : #include "lib_disc/common/function_group.h"
      41              : #include "lib_disc/common/groups_util.h"
      42              : #include "lib_disc/quadrature/quadrature.h"
      43              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      44              : #include "lib_disc/spatial_disc/user_data/std_user_data.h"
      45              : #include "lib_disc/reference_element/reference_mapping_provider.h"
      46              : 
      47              : 
      48              : namespace ug{
      49              : 
      50              : /**
      51              :  * Class for StdDependentUserData interface to scalar values from GridFunction objects.
      52              :  *
      53              :  * This class provides a StdDependentUserData interface to scalar values from GridFunction
      54              :  * objects so that they can be used in import parameters. Note that the GridFunction object
      55              :  * must have the same FunctionPattern as the owner of the import parameter.
      56              :  *
      57              :  * REMARK:
      58              :  * This class is used to reuse the unknowns of variables of discretizations. It provides
      59              :  * "derivatives w.r.t. the unknowns", too. Note that in this case, the GridFunction object
      60              :  * must be the same as the solution. An attempt to use a grid function based on a different
      61              :  * ApproximationSpace would lead to errors. Consider ExplicitGridFunctionValue
      62              :  * for this purpose instead.
      63              :  */
      64              : template <typename TGridFunction>
      65              : class GridFunctionNumberData
      66              : : public StdDependentUserData<GridFunctionNumberData<TGridFunction>,
      67              :   number, TGridFunction::dim>
      68              : {
      69              :         public:
      70              :                 //      world dimension of grid function
      71              :                 static const int dim = TGridFunction::dim;
      72              : 
      73              :                 private:
      74              :                 // grid function
      75              :                 SmartPtr<TGridFunction> m_spGridFct;
      76              : 
      77              :                 //      component of function
      78              :                 size_t m_fct;
      79              : 
      80              :                 //      local finite element id
      81              :                 LFEID m_lfeID;
      82              : 
      83              :         public:
      84              :                 /// constructor
      85            0 :                 GridFunctionNumberData(SmartPtr<TGridFunction> spGridFct, const char* cmp)
      86            0 :                 {
      87            0 :                         assign(spGridFct, cmp);
      88            0 :                 }
      89              : 
      90              :                 GridFunctionNumberData(){}
      91              : 
      92            0 :                 void assign(SmartPtr<TGridFunction> spGridFct, const char* cmp)
      93              :                 {
      94            0 :                         m_spGridFct = spGridFct;
      95            0 :                         this->set_functions(cmp);
      96              : 
      97              :                         //      get function id of name
      98            0 :                         m_fct = spGridFct->fct_id_by_name(cmp);
      99              : 
     100              :                         //      check that function exists
     101            0 :                         if(m_fct >= spGridFct->num_fct())
     102            0 :                                 UG_THROW("GridFunctionNumberData: Function space does not contain"
     103              :                                                 " a function with name " << cmp << ".");
     104              : 
     105              :                         //      local finite element id
     106            0 :                         m_lfeID = spGridFct->local_finite_element_id(m_fct);
     107            0 :                 }
     108              : 
     109            0 :                 virtual bool continuous() const
     110              :                 {
     111            0 :                         return LocalFiniteElementProvider::continuous(m_lfeID);
     112              :                 }
     113              : 
     114              :                 template <int refDim>
     115            0 :                 void eval_and_deriv(number vValue[],
     116              :                                     const MathVector<dim> vGlobIP[],
     117              :                                     number time, int si,
     118              :                                     GridObject* elem,
     119              :                                     const MathVector<dim> vCornerCoords[],
     120              :                                     const MathVector<refDim> vLocIP[],
     121              :                                     const size_t nip,
     122              :                                     LocalVector* u,
     123              :                                     bool bDeriv,
     124              :                                     int s,
     125              :                                     std::vector<std::vector<number> > vvvDeriv[],
     126              :                                     const MathMatrix<refDim, dim>* vJT = NULL) const
     127              :                 {
     128              :                         //      reference object id
     129            0 :                         const ReferenceObjectID roid = elem->reference_object_id();
     130              : 
     131              :                         //      get trial space
     132              :                         try{
     133              :                                 const LocalShapeFunctionSet<refDim>& rTrialSpace =
     134            0 :                                                 LocalFiniteElementProvider::get<refDim>(roid, m_lfeID);
     135              : 
     136              :                                 //      memory for shapes
     137              :                                 std::vector<number> vShape;
     138              :                                 //      memory for indices
     139              :                                 std::vector<DoFIndex> ind;
     140              : 
     141              :                                 //      loop ips
     142            0 :                                 for(size_t ip = 0; ip < nip; ++ip)
     143              :                                 {
     144              :                                         //      evaluate at shapes at ip
     145            0 :                                         rTrialSpace.shapes(vShape, vLocIP[ip]);
     146              : 
     147              :                                         //      get multiindices of element
     148            0 :                                         m_spGridFct->dof_indices(elem, m_fct, ind);
     149              : 
     150              :                                         //      compute solution at integration point
     151            0 :                                         vValue[ip] = 0.0;
     152            0 :                                         for(size_t sh = 0; sh < vShape.size(); ++sh)
     153              :                                         {
     154            0 :                                                 const number valSH = DoFRef(*m_spGridFct, ind[sh]);
     155            0 :                                                 vValue[ip] += valSH * vShape[sh];
     156              :                                         }
     157              :                                 }
     158              : 
     159            0 :                                 if(bDeriv){
     160            0 :                                         for(size_t ip = 0; ip < nip; ++ip){
     161              :                                                 //      evaluate at shapes at ip
     162            0 :                                                 rTrialSpace.shapes(vShape, vLocIP[ip]);
     163              : 
     164            0 :                                                 for(size_t sh = 0; sh < vShape.size(); ++sh)
     165            0 :                                                         vvvDeriv[ip][0][sh] = vShape[sh];
     166              :                                         }
     167              :                                 }
     168            0 :                         }
     169            0 :                         UG_CATCH_THROW("GridFunctionNumberData: Shape Function Set missing for"
     170              :                                         " Reference Object: "<<roid<<", Trial Space: "
     171              :                                         <<m_lfeID<<", refDim="<<refDim);
     172              : 
     173            0 :                 }
     174              :         
     175            0 :                 virtual void operator() (number& value,
     176              :                                                                         const MathVector<dim>& globIP,
     177              :                                                                         number time, int si,
     178              :                                                                         Vertex* vrt) const
     179              :                 {
     180              :                         std::vector<DoFIndex> ind;
     181            0 :                         if (m_spGridFct->dof_indices(vrt, m_fct, ind) != 1)
     182            0 :                                 UG_THROW ("GridFunctionNumberData: Values at vertices of the grid function are not uniquely defined.");
     183            0 :                         value = DoFRef(*m_spGridFct, ind[0]);
     184            0 :                 }
     185              : };
     186              : 
     187              : /**
     188              :  * Class for StdDependentUserData interface to vectors from GridFunction objects.
     189              :  *
     190              :  * This class provides a StdDependentUserData interface to vectors from GridFunction
     191              :  * objects so that they can be used in import parameters. Note that the GridFunction object
     192              :  * must have the same FunctionPattern as the owner of the import parameter.
     193              :  *
     194              :  * REMARK:
     195              :  * This class is used to reuse the unknowns of variables of discretizations. It provides
     196              :  * "derivatives w.r.t. the unknowns", too. Note that in this case the GridFunction object
     197              :  * must be the same as the solution. An attempt to use a grid function based on a different
     198              :  * ApproximationSpace would lead to errors. Consider ExplicitGridFunctionVector
     199              :  * for this purpose instead.
     200              :  */
     201              : template <typename TGridFunction>
     202              : class GridFunctionVectorData
     203              : : public StdDependentUserData<GridFunctionVectorData<TGridFunction>,
     204              :   MathVector<TGridFunction::dim>, TGridFunction::dim>
     205              : {
     206              :         public:
     207              :         //      world dimension of grid function
     208              :         static const int dim = TGridFunction::dim;
     209              : 
     210              :         private:
     211              :         // grid function
     212              :         SmartPtr<TGridFunction> m_spGridFct;
     213              : 
     214              :         //      component of function
     215              :         size_t m_vfct[dim];
     216              : 
     217              :         //      local finite element id
     218              :         LFEID m_vlfeID[dim];
     219              : 
     220              :         public:
     221              :         /// constructor
     222            0 :         GridFunctionVectorData(SmartPtr<TGridFunction> spGridFct, const char* cmp)
     223            0 :         : m_spGridFct(spGridFct)
     224              :         {
     225            0 :                 this->set_functions(cmp);
     226              : 
     227              :                 //      create function group of this elem disc
     228              :                 try{
     229              :                         //      get strings
     230            0 :                         std::string fctString = std::string(cmp);
     231              : 
     232              :                         //      tokenize strings and select functions
     233              :                         std::vector<std::string> tokens;
     234            0 :                         TokenizeString(fctString, tokens, ',');
     235              : 
     236            0 :                         for(size_t i = 0; i < tokens.size(); ++i)
     237            0 :                                 RemoveWhitespaceFromString(tokens[i]);
     238              : 
     239            0 :                         if((int)tokens.size() != dim)
     240            0 :                                 UG_THROW("GridFunctionVectorData: Needed "<<dim<<" components "
     241              :                                          "in symbolic function names, but given: "<<cmp);
     242              : 
     243              :                         //      get function id of name
     244            0 :                         for(int i = 0; i < dim; ++i){
     245            0 :                                 m_vfct[i] = spGridFct->fct_id_by_name(tokens[i].c_str());
     246            0 :                                 m_vlfeID[i] = spGridFct->local_finite_element_id(m_vfct[i]);
     247              :                         }
     248              : 
     249            0 :                 }UG_CATCH_THROW("GridFunctionVectorData: Cannot find  some symbolic function "
     250              :                                 "name in '"<<cmp<<"'.");
     251            0 :         };
     252              : 
     253              :         GridFunctionVectorData(SmartPtr<TGridFunction> spGridFct, std::vector<std::string> vCmp)
     254              :         : m_spGridFct(spGridFct)
     255              :         {
     256              :                 this->set_functions(vCmp);
     257              : 
     258              :                 //      create function group of this elem disc
     259              :                 try
     260              :                 {
     261              :                         if ((int)vCmp.size() != dim)
     262              :                                 UG_THROW("GridFunctionVectorData: Needed "<<dim<<" components "
     263              :                                                  "in symbolic function names, but given: "<< (int) vCmp.size());
     264              : 
     265              :                         //      get function id of name
     266              :                         for (size_t i = 0; i < (size_t) dim; ++i)
     267              :                         {
     268              :                                 m_vfct[i] = spGridFct->fct_id_by_name(vCmp[i].c_str());
     269              :                                 m_vlfeID[i] = spGridFct->local_finite_element_id(m_vfct[i]);
     270              :                         }
     271              : 
     272              :                 }UG_CATCH_THROW("GridFunctionVectorData: Cannot find some symbolic function "
     273              :                                 "name in component vector.");
     274              :         }
     275              : 
     276            0 :         virtual bool continuous() const
     277              :         {
     278            0 :                 for(int i = 0; i < dim; ++i)
     279            0 :                         if(!LocalFiniteElementProvider::continuous(m_vlfeID[i]))
     280              :                                 return false;
     281              :                 return true;
     282              :         }
     283              : 
     284              :         template <int refDim>
     285            0 :         void eval_and_deriv(MathVector<dim> vValue[],
     286              :                             const MathVector<dim> vGlobIP[],
     287              :                             number time, int si,
     288              :                             GridObject* elem,
     289              :                             const MathVector<dim> vCornerCoords[],
     290              :                             const MathVector<refDim> vLocIP[],
     291              :                             const size_t nip,
     292              :                             LocalVector* u,
     293              :                             bool bDeriv,
     294              :                             int s,
     295              :                             std::vector<std::vector<MathVector<dim> > > vvvDeriv[],
     296              :                             const MathMatrix<refDim, dim>* vJT = NULL) const
     297              :         {
     298              :                 //      reference object id
     299            0 :                 const ReferenceObjectID roid = elem->reference_object_id();
     300              : 
     301              :                 //      memory for shapes
     302              :                 std::vector<number> vShape;
     303              :                 //      memory for indices
     304              :                 std::vector<DoFIndex> ind;
     305              : 
     306              :                 //      loop ips
     307              :                 try{
     308            0 :                         for(size_t ip = 0; ip < nip; ++ip)
     309              :                         {
     310            0 :                                 for(int d = 0; d < dim; ++d)
     311              :                                 {
     312              :                                         const LocalShapeFunctionSet<refDim>& rTrialSpace =
     313            0 :                                                         LocalFiniteElementProvider::get<refDim>(roid, m_vlfeID[d]);
     314              : 
     315              :                                         //      evaluate at shapes at ip
     316            0 :                                         rTrialSpace.shapes(vShape, vLocIP[ip]);
     317              : 
     318              :                                         //      get multiindices of element
     319            0 :                                         m_spGridFct->dof_indices(elem, m_vfct[d], ind);
     320              : 
     321              :                                         //      compute solution at integration point
     322            0 :                                         vValue[ip][d] = 0.0;
     323            0 :                                         for(size_t sh = 0; sh < vShape.size(); ++sh)
     324              :                                         {
     325            0 :                                                 const number valSH = DoFRef( *m_spGridFct, ind[sh]);
     326            0 :                                                 vValue[ip][d] += valSH * vShape[sh];
     327              :                                         }
     328              :                                 }
     329              :                         }
     330              : 
     331              : 
     332            0 :                         if(bDeriv){
     333            0 :                                 for(size_t ip = 0; ip < nip; ++ip){
     334            0 :                                         for(int d = 0; d < dim; ++d)
     335              :                                         {
     336              :                                                 const LocalShapeFunctionSet<refDim>& rTrialSpace =
     337            0 :                                                                 LocalFiniteElementProvider::get<refDim>(roid, m_vlfeID[d]);
     338              :                                                 //      evaluate at shapes at ip
     339            0 :                                                 rTrialSpace.shapes(vShape, vLocIP[ip]);
     340              : 
     341            0 :                                                 for(size_t sh = 0; sh < vShape.size(); ++sh)
     342            0 :                                                         vvvDeriv[ip][d][sh][d] = vShape[sh];
     343              :                                         }
     344              :                                 }
     345              :                         }
     346              : 
     347              : 
     348            0 :                 }UG_CATCH_THROW("GridFunctionVectorData: Reference Object: "
     349              :                                 <<roid<<", refDim="<<refDim);
     350            0 :         }
     351              :         
     352            0 :         virtual void operator() (MathVector<dim>& value,
     353              :                                                                                 const MathVector<dim>& globIP,
     354              :                                                                                 number time, int si,
     355              :                                                                                 Vertex* vrt) const
     356              :         {
     357              :                 std::vector<DoFIndex> ind;
     358            0 :                 for(int d = 0; d < dim; ++d)
     359              :                 {
     360            0 :                         if (m_spGridFct->dof_indices(vrt, m_vfct[d], ind) != 1)
     361            0 :                                 UG_THROW ("GridFunctionVectorData: Values at vertices of the grid function are not uniquely defined.");
     362            0 :                         value[d] = DoFRef(*m_spGridFct, ind[0]);
     363              :                 }
     364            0 :         }
     365              : };
     366              : 
     367              : 
     368              : /**
     369              :  * Class for StdDependentUserData interface to the gradient of scalar values from GridFunction objects.
     370              :  *
     371              :  * This class provides a StdDependentUserData interface to the gradient of scalar values
     372              :  * from GridFunction objects so that they can be used in import parameters. Note that the
     373              :  * GridFunction object must have the same FunctionPattern as the owner of the import parameter.
     374              :  *
     375              :  * REMARK:
     376              :  * This class is used to reuse the unknowns of variables of discretizations. It provides
     377              :  * "derivatives w.r.t. the unknowns", too. Note that in this case the GridFunction object
     378              :  * must be the same as the solution. An attempt to use a grid function based on a different
     379              :  * ApproximationSpace would lead to errors. Consider ExplicitGridFunctionGradient
     380              :  * for this purpose instead.
     381              :  */
     382              : template <typename TGridFunction>
     383              : class GridFunctionGradientData
     384              : : public StdDependentUserData<GridFunctionGradientData<TGridFunction> ,
     385              :   MathVector<TGridFunction::dim>, TGridFunction::dim>
     386              : {
     387              :         public:
     388              :         //      world dimension of grid function
     389              :         static const int dim = TGridFunction::dim;
     390              : 
     391              :         private:
     392              :         // grid function
     393              :         SmartPtr<TGridFunction> m_spGridFct;
     394              : 
     395              :         //      component of function
     396              :         size_t m_fct;
     397              : 
     398              :         //      local finite element id
     399              :         LFEID m_lfeID;
     400              : 
     401              :         public:
     402              :         /// constructor
     403            0 :         GridFunctionGradientData(SmartPtr<TGridFunction> spGridFct, const char* cmp)
     404            0 :         : m_spGridFct(spGridFct)
     405              :         {
     406            0 :                 this->set_functions(cmp);
     407              : 
     408              :                 //      get function id of name
     409            0 :                 m_fct = spGridFct->fct_id_by_name(cmp);
     410              : 
     411              :                 //      check that function exists
     412            0 :                 if(m_fct >= spGridFct->num_fct())
     413            0 :                         UG_THROW("GridFunctionGradientData: Function space does not contain"
     414              :                                         " a function with name " << cmp << ".");
     415              : 
     416              :                 //      local finite element id
     417            0 :                 m_lfeID = spGridFct->local_finite_element_id(m_fct);
     418            0 :         };
     419              : 
     420            0 :         virtual bool continuous() const
     421              :         {
     422            0 :                 return false;
     423              :         }
     424              : 
     425              :         template <int refDim>
     426            0 :         void eval_and_deriv(MathVector<dim> vValue[],
     427              :                             const MathVector<dim> vGlobIP[],
     428              :                             number time, int si,
     429              :                             GridObject* elem,
     430              :                             const MathVector<dim> vCornerCoords[],
     431              :                             const MathVector<refDim> vLocIP[],
     432              :                             const size_t nip,
     433              :                             LocalVector* u,
     434              :                             bool bDeriv,
     435              :                             int s,
     436              :                             std::vector<std::vector<MathVector<dim> > > vvvDeriv[],
     437              :                             const MathMatrix<refDim, dim>* vJT = NULL) const
     438              :         {
     439              :                 //      reference object id
     440            0 :                 const ReferenceObjectID roid = elem->reference_object_id();
     441              : 
     442              :                 //      get reference element mapping by reference object id
     443            0 :                 std::vector<MathMatrix<refDim, dim> > vJTTmp(nip);
     444            0 :                 if(vJT == NULL){
     445              :                         try{
     446              :                                 DimReferenceMapping<refDim, dim>& mapping
     447              :                                 = ReferenceMappingProvider::get<refDim, dim>(roid, vCornerCoords);
     448              : 
     449              :                                 //      compute transformation matrices
     450            0 :                                 mapping.jacobian_transposed(&(vJTTmp[0]), vLocIP, nip);
     451              : 
     452              :                                 //      store tmp Gradient
     453              :                                 vJT = &(vJTTmp[0]);
     454            0 :                         }UG_CATCH_THROW("GridFunctionGradientData: failed.");
     455              :                 }
     456              : 
     457              :                 //      get trial space
     458              :                 try{
     459              :                         const LocalShapeFunctionSet<refDim>& rTrialSpace =
     460            0 :                                         LocalFiniteElementProvider::get<refDim>(roid, m_lfeID);
     461              : 
     462              :                         //      storage for shape function at ip
     463              :                         std::vector<MathVector<refDim> > vLocGrad;
     464              :                         MathVector<refDim> locGrad;
     465              : 
     466              :                         //      Reference Mapping
     467              :                         MathMatrix<dim, refDim> JTInv;
     468              : 
     469              :                         //      loop ips
     470            0 :                         for(size_t ip = 0; ip < nip; ++ip)
     471              :                         {
     472              :                                 //      evaluate at shapes at ip
     473            0 :                                 rTrialSpace.grads(vLocGrad, vLocIP[ip]);
     474              : 
     475              :                                 //      get multiindices of element
     476              :                                 std::vector<DoFIndex > ind;
     477            0 :                                 m_spGridFct->dof_indices(elem, m_fct, ind);
     478              : 
     479              :                                 //      compute grad at ip
     480              :                                 VecSet(locGrad, 0.0);
     481            0 :                                 for(size_t sh = 0; sh < vLocGrad.size(); ++sh)
     482              :                                 {
     483            0 :                                         const number valSH = DoFRef( *m_spGridFct, ind[sh]);
     484              :                                         VecScaleAppend(locGrad, valSH, vLocGrad[sh]);
     485              :                                 }
     486              : 
     487            0 :                                 RightInverse (JTInv, vJT[ip]);
     488            0 :                                 MatVecMult(vValue[ip], JTInv, locGrad);
     489              :                         }
     490            0 :                 }
     491            0 :                 UG_CATCH_THROW("GridFunctionNumberData: Shape Function Set missing for"
     492              :                                 " Reference Object: "<<roid<<", Trial Space: "
     493              :                                 <<m_lfeID<<", refDim="<<refDim);
     494              : 
     495            0 :                 if(bDeriv)
     496            0 :                         UG_THROW("Not implemented.");
     497            0 :         }
     498              : };
     499              : 
     500              : 
     501              : /**
     502              :  * \brief Retrieve component of gradient of GridFunction
     503              :  * \details Helper construct to retrieve specific vector element of the gradient 
     504              :  *   of a GridFunction inside loops (e.g. integrals) over that GridFunction.
     505              :  * \code{.lua}
     506              :    -- integrate the second component of the gradient of the GridFunction u
     507              :    Integrate( GridFunctionGradientComponentData(u, "c", 2), u )
     508              :  * \endcode
     509              :  */
     510              : template <typename TGridFunction>
     511              : class GridFunctionGradientComponentData
     512              : : public StdDependentUserData<GridFunctionGradientComponentData<TGridFunction>,
     513              :   number, TGridFunction::dim>
     514              : {
     515              :         public:
     516              :         ///     World dimension of GridFunction m_spGridFct
     517              :         static const int dim = TGridFunction::dim;
     518              : 
     519              :         private:
     520              :         ///     GridFunction to loop over
     521              :         SmartPtr<TGridFunction> m_spGridFct;
     522              : 
     523              :         ///     Component ID of function to be used
     524              :         size_t m_fct;
     525              : 
     526              :         ///     Component index of gradient to return (0-based)
     527              :         size_t m_component;
     528              : 
     529              :         ///     Local Finite Element ID
     530              :         LFEID m_lfeID;
     531              : 
     532              :         public:
     533              :         /**
     534              :          * \brief Constructor
     535              :          * \param[in] spGridFct GridFunction to loop over
     536              :          * \param[in] cmp Name of the GridFunction's function to calculate gradient of
     537              :          * \param[in] component Index of gradient vector component to return (1-based)
     538              :          */
     539            0 :         GridFunctionGradientComponentData( SmartPtr<TGridFunction> spGridFct,
     540              :                                            const char* cmp,
     541              :                                            size_t component /* 1-based */ )
     542            0 :         : m_spGridFct( spGridFct )
     543              :         {
     544            0 :                 this->set_functions(cmp);
     545              : 
     546              :                 //      check validity of component index
     547            0 :                 if ( component > static_cast<size_t>(dim) && component > 0 ) {
     548            0 :                         UG_THROW( "GridFunctionGradientComponentData: Requested component index "
     549              :                                         << component << " out of bounds [1," << dim << "]." );
     550              :                 }
     551            0 :                 m_component = component - 1;
     552              : 
     553              :                 //      get function id of name
     554            0 :                 m_fct = spGridFct->fct_id_by_name( cmp );
     555              : 
     556              :                 //      check that function exists
     557            0 :                 if( m_fct >= spGridFct->num_fct() ) {
     558            0 :                         UG_THROW( "GridFunctionGradientComponentData: Function space does not contain"
     559              :                                         " a function with name " << cmp << "." );
     560              :                 }
     561              : 
     562              :                 //      local finite element id
     563            0 :                 m_lfeID = spGridFct->local_finite_element_id( m_fct );
     564            0 :         };
     565              : 
     566            0 :         virtual bool continuous() const
     567              :         {
     568            0 :                 return false;
     569              :         }
     570              : 
     571              :         /**
     572              :          * \param[out] vValue Array of the <tt>nip</tt> gradient components
     573              :          */
     574              :         template <int refDim>
     575            0 :         void eval_and_deriv(number vValue[],
     576              :                             const MathVector<dim> vGlobIP[],
     577              :                             number time, int si,
     578              :                             GridObject* elem,
     579              :                             const MathVector<dim> vCornerCoords[],
     580              :                             const MathVector<refDim> vLocIP[],
     581              :                             const size_t nip,
     582              :                             LocalVector* u,
     583              :                             bool bDeriv,
     584              :                             int s,
     585              :                             std::vector<std::vector<number> > vvvDeriv[],
     586              :                             const MathMatrix<refDim, dim>* vJT = NULL) const
     587              :         {
     588              :                 //      reference object id
     589            0 :                 const ReferenceObjectID roid = elem->reference_object_id();
     590              : 
     591              :                 //      get reference element mapping by reference object id
     592            0 :                 std::vector<MathMatrix<refDim, dim> > vJTTmp( nip );
     593            0 :                 if( vJT == NULL ) {
     594              :                         try{
     595              :                                 DimReferenceMapping<refDim, dim>& mapping
     596              :                                 = ReferenceMappingProvider::get< refDim, dim >( roid, vCornerCoords );
     597              : 
     598              :                                 //      compute transformation matrices
     599            0 :                                 mapping.jacobian_transposed( &(vJTTmp[0]), vLocIP, nip );
     600              : 
     601              :                                 //      store tmp Gradient
     602              :                                 vJT = &(vJTTmp[0]);
     603            0 :                         } UG_CATCH_THROW( "GridFunctionGradientComponentData: failed.");
     604              :                 }
     605              : 
     606              :                 //      get trial space
     607              :                 try {
     608              :                         const LocalShapeFunctionSet<refDim>& rTrialSpace =
     609            0 :                                         LocalFiniteElementProvider::get<refDim>( roid, m_lfeID );
     610              : 
     611              :                         //      storage for shape function at ip
     612              :                         std::vector<MathVector<refDim> > vLocGrad;
     613              :                         MathVector<refDim> locGrad;
     614              :                         std::vector<MathVector<dim> > vValueVec;
     615            0 :                         vValueVec.resize( nip );
     616              : 
     617              :                         //      Reference Mapping
     618              :                         MathMatrix<dim, refDim> JTInv;
     619              : 
     620              :                         //      loop ips
     621            0 :                         for( size_t ip = 0; ip < nip; ++ip ) {
     622              :                                 //      evaluate at shapes at ip
     623            0 :                                 rTrialSpace.grads( vLocGrad, vLocIP[ip] );
     624              : 
     625              :                                 //      get multiindices of element
     626              :                                 std::vector<DoFIndex> ind;
     627            0 :                                 m_spGridFct->dof_indices( elem, m_fct, ind );
     628              : 
     629              :                                 //      compute grad at ip
     630              :                                 VecSet( locGrad, 0.0 );
     631            0 :                                 for( size_t sh = 0; sh < vLocGrad.size(); ++sh ) {
     632            0 :                                         const number valSH = DoFRef( *m_spGridFct, ind[sh] );
     633              :                                         VecScaleAppend( locGrad, valSH, vLocGrad[sh] );
     634              :                                 }
     635              : 
     636            0 :                                 RightInverse( JTInv, vJT[ip] );
     637              :                                 MatVecMult( vValueVec[ip], JTInv, locGrad );
     638              : 
     639            0 :                                 vValue[ip] = vValueVec[ip][m_component];
     640              : 
     641            0 :                                 if(bDeriv){
     642            0 :                                         for( size_t ip = 0; ip < nip; ++ip ) {
     643              :                                                 UG_ASSERT(vvvDeriv[ip].size() == 1,
     644              :                                                           "Single component expected, but "<<vvvDeriv[ip].size())
     645              :                                                 UG_ASSERT(vvvDeriv[ip][0].size() == vLocGrad.size(),
     646              :                                                           "Wrong number sh: "<<vvvDeriv[ip][0].size()<<", but expected: "<<vLocGrad.size())
     647              : 
     648            0 :                                                 for( size_t sh = 0; sh < vLocGrad.size(); ++sh ) {
     649              :                                                         MatVecMult( vValueVec[ip], JTInv, vLocGrad[sh] );
     650            0 :                                                         vvvDeriv[ip][0][sh] = vValueVec[ip][m_component];
     651              :                                                 }
     652              :                                         }
     653              :                                 }
     654              :                         }
     655            0 :                 }
     656            0 :                 UG_CATCH_THROW("GridFunctionNumberData: Shape Function Set missing for"
     657              :                                 " Reference Object: "<<roid<<", Trial Space: "
     658              :                                 <<m_lfeID<<", refDim="<<refDim);
     659            0 :         }
     660              : };
     661              : 
     662              : } // end namespace ug
     663              : 
     664              : #endif /* __H__UG__LIB_DISC__FUNCTION_SPACE__GRID_FUNCTION_USER_DATA__ */
        

Generated by: LCOV version 2.0-1