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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Authors: Andreas Vogel, Christian Wehner
       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              : /*
      34              :  *      an adaption of interpolate.h to maximum error computation
      35              :  */
      36              : 
      37              : #ifndef __H__UG__LIB_DISC__MAX__ERROR__
      38              : #define __H__UG__LIB_DISC__MAX__ERROR__
      39              : 
      40              : #include "common/common.h"
      41              : #include "common/util/smart_pointer.h"
      42              : 
      43              : #include "lib_grid/tools/subset_group.h"
      44              : 
      45              : #include "lib_disc/common/groups_util.h"
      46              : #include "lib_disc/local_finite_element/local_finite_element_provider.h"
      47              : #include "lib_disc/spatial_disc/user_data/const_user_data.h"
      48              : #include "lib_disc/reference_element/reference_mapping.h"
      49              : #include "lib_disc/domain_util.h"
      50              : 
      51              : #ifdef UG_FOR_LUA
      52              : #include "bindings/lua/lua_user_data.h"
      53              : #endif
      54              : 
      55              : namespace ug{
      56              : 
      57              : ////////////////////////////////////////////////////////////////////////////////
      58              : // Compute max error on Vertices only
      59              : ////////////////////////////////////////////////////////////////////////////////
      60              :         
      61              : /**
      62              :  * This function computes max error of a grid function on a vertex loop. Thus, it can only
      63              :  * be used if all degrees of freedom are located in the vertices only (e.g. P1
      64              :  * finite elements). In those cases it is faster than the element by element
      65              :  * loop.
      66              :  *
      67              :  * @param[in] globalMaxError            reference to global max error
      68              :  * @param[in] spInterpolFunction        data providing exact solution
      69              :  * @param[out] spGridFct                        grid function
      70              :  * @param[in] fct                                       symbolic name of function component
      71              :  * @param[in] ssGrp                                     subsets, where to compute max error
      72              :  * @param[in] time                                      time point
      73              :  */
      74              : template <typename TGridFunction>
      75            0 : void MaxErrorOnVertices(number& globalMaxError,SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
      76              :                            SmartPtr<TGridFunction> spGridFct,
      77              :                            size_t fct,
      78              :                            number time,
      79              :                            const SubsetGroup& ssGrp)
      80              : {
      81              : //      domain type and position_type
      82              :         typedef typename TGridFunction::domain_type domain_type;
      83              :         typedef typename domain_type::position_type position_type;
      84              : 
      85              : // get position accessor
      86              :         const typename domain_type::position_accessor_type& aaPos
      87            0 :                                                                                 = spGridFct->domain()->position_accessor();
      88              : 
      89              :         std::vector<DoFIndex> ind;
      90              :         typename TGridFunction::template dim_traits<0>::const_iterator iterEnd, iter;
      91              : 
      92            0 :         for(size_t i = 0; i < ssGrp.size(); ++i)
      93              :         {
      94              :         //      get subset index
      95              :                 const int si = ssGrp[i];
      96              : 
      97              :         //      skip if function is not defined in subset
      98            0 :                 if(!spGridFct->is_def_in_subset(fct, si)) continue;
      99              : 
     100              :         //      iterate over all elements
     101            0 :                 iterEnd = spGridFct->template end<Vertex>(si);
     102            0 :                 iter = spGridFct->template begin<Vertex>(si);
     103            0 :                 for(; iter != iterEnd; ++iter)
     104              :                 {
     105              :                 //      get element
     106              :                         Vertex* vrt = *iter;
     107              : 
     108              :                 //      global position
     109              :                         position_type glob_pos = aaPos[vrt];
     110              : 
     111              :                 //      value at position
     112              :                         number val;
     113            0 :                         (*spInterpolFunction)(val, glob_pos, time, si);
     114              : 
     115              :                 //      get multiindices of element
     116              :                         spGridFct->dof_indices(vrt, fct, ind);
     117              : 
     118              :                 //      loop all dofs
     119            0 :                         for(size_t i = 0; i < ind.size(); ++i)
     120              :                         {
     121              :                         //      compute error
     122            0 :                                 number localError = std::abs(DoFRef((*spGridFct), ind[i])-val);
     123            0 :                                 if (localError>globalMaxError) globalMaxError=localError;
     124              :                         }
     125              :                 }
     126              :         }
     127            0 : }
     128              : 
     129              : ////////////////////////////////////////////////////////////////////////////////
     130              : // Maximum error on Elements
     131              : ////////////////////////////////////////////////////////////////////////////////
     132              : 
     133              : /**
     134              :  * This function computes maximum error of a grid function on an element by element loop. 
     135              :  *
     136              :  * @param[in] globalMaxError            reference to global max error
     137              :  * @param[in] spInterpolFunction        data providing exact solution
     138              :  * @param[out] spGridFct                        interpolated grid function
     139              :  * @param[in] fct                                       symbolic name of function component
     140              :  * @param[in] si                                        subset
     141              :  * @param[in] time                                      time point
     142              :  */
     143              : template <typename TElem, typename TGridFunction>
     144            0 : void MaxErrorOnElements(
     145              :                 number& globalMaxError,
     146              :                 SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     147              :                 SmartPtr<TGridFunction> spGridFct, size_t fct, int si, number time)
     148              : {
     149              : //      get reference element type
     150              :         typedef typename reference_element_traits<TElem>::reference_element_type
     151              :                                 ref_elem_type;
     152              :         const ReferenceObjectID roid = ref_elem_type::REFERENCE_OBJECT_ID;
     153              : 
     154              : //      dimension of reference element
     155              :         const int dim = ref_elem_type::dim;
     156              : 
     157              : //      domain type and position_type
     158              :         typedef typename TGridFunction::domain_type domain_type;
     159              :         typedef typename domain_type::position_type position_type;
     160              : 
     161              : //      get iterators
     162              :         typename TGridFunction::template traits<TElem>::const_iterator iterEnd, iter;
     163            0 :         iterEnd = spGridFct->template end<TElem>(si);
     164            0 :         iter = spGridFct->template begin<TElem>(si);
     165              : 
     166              : //      check if something to do:
     167            0 :         if(iter == iterEnd) return;
     168              : 
     169              : //      id of shape functions used
     170            0 :         LFEID id = spGridFct->local_finite_element_id(fct);
     171              : 
     172              : //      get trial space
     173              :         const LocalShapeFunctionSet<dim>& trialSpace =
     174              :                         LocalFiniteElementProvider::get<dim>(roid, id);
     175              : 
     176              : //      number of dofs on element
     177            0 :         const size_t nsh = trialSpace.num_sh();
     178              : 
     179              : //      load local positions of dofs for the trial space on element
     180            0 :         std::vector<MathVector<dim> > loc_pos(nsh);
     181            0 :         for(size_t i = 0; i < nsh; ++i)
     182            0 :                 if(!trialSpace.position(i, loc_pos[i]))
     183            0 :                         UG_THROW("MaxErrorOnElem: Cannot find meaningful"
     184              :                                         " local positions of dofs.");
     185              : 
     186              : //      create a reference mapping
     187              :         ReferenceMapping<ref_elem_type, domain_type::dim> mapping;
     188              : 
     189              : //      iterate over all elements
     190            0 :         for( ; iter != iterEnd; ++iter)
     191              :         {
     192              :         //      get element
     193              :                 TElem* elem = *iter;
     194              : 
     195              :         //      get all corner coordinates
     196              :                 std::vector<position_type> vCorner;
     197            0 :                 CollectCornerCoordinates(vCorner, *elem, *spGridFct->domain());
     198              : 
     199              :         //      update the reference mapping for the corners
     200            0 :                 mapping.update(&vCorner[0]);
     201              : 
     202              :         //      get multiindices of element
     203              :                 std::vector<DoFIndex> ind;
     204              :                 spGridFct->dof_indices(elem, fct, ind);
     205              : 
     206              :         //      check multi indices
     207            0 :                 if(ind.size() != nsh)
     208            0 :                         UG_THROW("MaxErrorOnElem: On subset "<<si<<": Number of shapes is "
     209              :                                         <<nsh<<", but got "<<ind.size()<<" multi indices.");
     210              : 
     211              :         //      loop all dofs
     212            0 :                 for(size_t i = 0; i < nsh; ++i)
     213              :                 {
     214              :                 //      global position
     215              :                         position_type glob_pos;
     216              : 
     217              :                 //  map local dof position to global position
     218            0 :                         mapping.local_to_global(glob_pos, loc_pos[i]);
     219              : 
     220              :                 //      value at position
     221              :                         number val;
     222            0 :                         (*spInterpolFunction)(val, glob_pos, time, si);
     223              :                         
     224              :                 //      compute error
     225            0 :                         number localError = std::abs(DoFRef((*spGridFct), ind[i])-val);
     226            0 :                         if (localError>globalMaxError) globalMaxError=localError;
     227              :                 }
     228              :         }
     229            0 : }
     230              : 
     231              : /**
     232              :  * This function computes maximum error of grid function on an element by element loop. 
     233              :  *
     234              :  * @param[in] globalMaxError            reference to global max error
     235              :  * @param[in] spInterpolFunction        data providing exact solution
     236              :  * @param[out] spGridFct                        grid function
     237              :  * @param[in] fct                                       symbolic name of function component
     238              :  * @param[in] ssGrp                                     subsets
     239              :  * @param[in] time                                      time point
     240              :  */
     241              : template <typename TGridFunction>
     242            0 : void MaxErrorOnElements(
     243              :                         number& globalMaxError,
     244              :                         SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     245              :                            SmartPtr<TGridFunction> spGridFct,
     246              :                            size_t fct,
     247              :                            number time,
     248              :                            const SubsetGroup& ssGrp)
     249              : {
     250              : //      loop subsets
     251            0 :         for(size_t i = 0; i < ssGrp.size(); ++i)
     252              :         {
     253              :         //      get subset index
     254              :                 const int si = ssGrp[i];
     255              : 
     256              :         //      skip if function is not defined in subset
     257            0 :                 if(!spGridFct->is_def_in_subset(fct, si)) continue;
     258              : 
     259              :         //      switch dimensions
     260              :                 try
     261              :                 {
     262            0 :                 const int dim = ssGrp.dim(i);
     263              : 
     264            0 :                 if(dim > TGridFunction::dim)
     265            0 :                         UG_THROW("MaxErrorOnElements: Dimension of subset is "<<dim<<", but "
     266              :                                  " World Dimension is "<<TGridFunction::dim<<". Cannot interpolate this.");
     267              : 
     268            0 :                 switch(dim)
     269              :                 {
     270              :                 case DIM_SUBSET_EMPTY_GRID: break;
     271              :                 case 0: /* \TODO: do nothing may be wrong */    break;
     272              :                 case 1:
     273            0 :                         MaxErrorOnElements<RegularEdge, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     274            0 :                         break;
     275              :                 case 2:
     276            0 :                         MaxErrorOnElements<Triangle, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     277            0 :                         MaxErrorOnElements<Quadrilateral, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     278            0 :                         break;
     279              :                 case 3:
     280            0 :                         MaxErrorOnElements<Tetrahedron, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     281            0 :                         MaxErrorOnElements<Hexahedron, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     282            0 :                         MaxErrorOnElements<Prism, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     283            0 :                         MaxErrorOnElements<Pyramid, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     284            0 :                         MaxErrorOnElements<Octahedron, TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, si, time);
     285            0 :                         break;
     286            0 :                 default: UG_THROW("MaxErrorOnElements: Dimension " <<dim<<
     287              :                                 " not possible for world dim "<<3<<".");
     288              :                 }
     289              :                 }
     290            0 :                 UG_CATCH_THROW("MaxErrorOnElements: Cannot interpolate on elements.");
     291              :         }
     292            0 : }
     293              : 
     294              : ////////////////////////////////////////////////////////////////////////////////
     295              : // MaxError routine
     296              : ////////////////////////////////////////////////////////////////////////////////
     297              : 
     298              : /// computes maximum error of a grid function on a subset
     299              : /**
     300              :  * This function computes the maximum error of a GridFunction. To evaluate the exact solution on every
     301              :  * point a functor must be passed.
     302              :  *
     303              :  * @param[in] spInterpolFunction        data providing exact solution
     304              :  * @param[out] spGridFct                        interpolated grid function
     305              :  * @param[in] cmp                                       symbolic name of function component
     306              :  * @param[in] subsets                           subsets (NULL = everywhere)
     307              :  * @param[in] time                                      time point
     308              :  * @returns       globalMaxError        maximum norm of difference
     309              :  */
     310              : template <typename TGridFunction>
     311            0 : number MaxError(
     312              :         SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     313              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     314              :                  const char* subsets, number time)
     315              : {
     316            0 :         number globalMaxError=0;
     317              : //      check, that values do not depend on a solution
     318            0 :         if(spInterpolFunction->requires_grid_fct())
     319            0 :                 UG_THROW("MaxError: The interpolation values depend on a grid function."
     320              :                                 " This is not allowed in the current implementation. Use constant,"
     321              :                                 " lua-callback or vrl-callback user data only (even within linkers).");
     322              : 
     323              : //      get function id of name
     324              :         const size_t fct = spGridFct->fct_id_by_name(cmp);
     325              : 
     326              : //      check that function found
     327            0 :         if(fct > spGridFct->num_fct())
     328            0 :                 UG_THROW("MaxError: Name of component '"<<cmp<<"' not found.");
     329              : 
     330              : //      check if fast P1 interpolation can be used
     331              :         // \TODO: This should be improved. Manifold admissible if space continuous
     332              :         bool bUseP1Interpolation = false;
     333            0 :         if(spGridFct->local_finite_element_id(fct).type() == LFEID::LAGRANGE &&
     334              :                         spGridFct->local_finite_element_id(fct).order() == 1)
     335              :                 bUseP1Interpolation = true;
     336              :         const bool bAllowManyfoldInterpolation =
     337              :                         (spGridFct->local_finite_element_id(fct).type() == LFEID::LAGRANGE);
     338              : 
     339              : //      create subset group
     340            0 :         SubsetGroup ssGrp(spGridFct->domain()->subset_handler());
     341            0 :         if(subsets != NULL)
     342              :         {
     343            0 :                 ssGrp.add(TokenizeString(subsets));
     344            0 :                 if(!bAllowManyfoldInterpolation)
     345            0 :                         if(!SameDimensionsInAllSubsets(ssGrp))
     346            0 :                                 UG_THROW("MaxError: Subsets '"<<subsets<<"' do not have same dimension."
     347              :                                                  "Can not integrate on subsets of different dimensions.");
     348              :         }
     349              :         else
     350              :         {
     351              :         //      add all subsets and remove lower dim subsets afterwards
     352            0 :                 ssGrp.add_all();
     353            0 :                 if(!bAllowManyfoldInterpolation)
     354            0 :                         RemoveLowerDimSubsets(ssGrp);
     355              :         }
     356              : 
     357              : //      forward
     358            0 :         if(bUseP1Interpolation)
     359            0 :                 MaxErrorOnVertices<TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, time, ssGrp);
     360              :         else
     361            0 :                 MaxErrorOnElements<TGridFunction>(globalMaxError,spInterpolFunction, spGridFct, fct, time, ssGrp);
     362              : 
     363              :         //      adjust parallel storage state
     364              : #ifdef UG_PARALLEL
     365              :         spGridFct->set_storage_type(PST_CONSISTENT);
     366              : #endif
     367            0 :         return globalMaxError;
     368              : }
     369              : 
     370              : template <typename TGridFunction>
     371            0 : number MaxError(SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     372              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     373              :                  number time)
     374              : {
     375            0 :         return MaxError(spInterpolFunction, spGridFct, cmp, NULL, time);
     376              : }
     377              : template <typename TGridFunction>
     378            0 : number MaxError(SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     379              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     380              :                  const char* subsets)
     381              : {
     382            0 :         return MaxError(spInterpolFunction, spGridFct, cmp, subsets, 0.0);
     383              : }
     384              : template <typename TGridFunction>
     385            0 : number MaxError(SmartPtr<UserData<number, TGridFunction::dim> > spInterpolFunction,
     386              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp)
     387              : {
     388            0 :         return MaxError(spInterpolFunction, spGridFct, cmp, NULL, 0.0);
     389              : }
     390              : 
     391              : ///////////////
     392              : // const data
     393              : ///////////////
     394              : 
     395              : template <typename TGridFunction>
     396            0 : number MaxError(number val,
     397              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     398              :                  const char* subsets, number time)
     399              : {
     400              :         static const int dim = TGridFunction::dim;
     401            0 :         SmartPtr<UserData<number, dim> > sp =
     402            0 :                         make_sp(new ConstUserNumber<dim>(val));
     403            0 :         return MaxError(sp, spGridFct, cmp, subsets, time);
     404              : }
     405              : template <typename TGridFunction>
     406            0 : number MaxError(number val,
     407              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     408              :                  number time)
     409              : {
     410            0 :         return MaxError(val, spGridFct, cmp, NULL, time);
     411              : }
     412              : template <typename TGridFunction>
     413            0 : number MaxError(number val,
     414              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     415              :                  const char* subsets)
     416              : {
     417            0 :         return MaxError(val, spGridFct, cmp, subsets, 0.0);
     418              : }
     419              : template <typename TGridFunction>
     420            0 : number MaxError(number val,
     421              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp)
     422              : {
     423            0 :         return MaxError(val, spGridFct, cmp, NULL, 0.0);
     424              : }
     425              : 
     426              : ///////////////
     427              : // lua data
     428              : ///////////////
     429              : 
     430              : #ifdef UG_FOR_LUA
     431              : template <typename TGridFunction>
     432            0 : number MaxError(const char* LuaFunction,
     433              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     434              :                  const char* subsets, number time)
     435              : {
     436              :         static const int dim = TGridFunction::dim;
     437            0 :         SmartPtr<UserData<number, dim> > sp =
     438              :                         LuaUserDataFactory<number, dim>::create(LuaFunction);
     439            0 :         return MaxError(sp, spGridFct, cmp, subsets, time);
     440              : }
     441              : template <typename TGridFunction>
     442            0 : number MaxError(const char* LuaFunction,
     443              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     444              :                  number time)
     445              : {       
     446            0 :         return MaxError(LuaFunction, spGridFct, cmp, NULL, time);
     447              : }
     448              : 
     449              : template <typename TGridFunction>
     450            0 : number MaxError(const char* LuaFunction,
     451              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp,
     452              :                  const char* subsets)
     453              : {       
     454            0 :         return MaxError(LuaFunction, spGridFct, cmp, subsets, 0.0);
     455              : }
     456              : template <typename TGridFunction>
     457            0 : number MaxError(const char* LuaFunction,
     458              :                  SmartPtr<TGridFunction> spGridFct, const char* cmp)
     459              : {       
     460            0 :         return MaxError(LuaFunction, spGridFct, cmp, NULL, 0.0);
     461              : }
     462              : #endif
     463              : 
     464              : 
     465              : } // namespace ug
     466              : 
     467              : #endif /*__H__UG__LIB_DISC__MAX__ERROR__*/
        

Generated by: LCOV version 2.0-1