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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-2017:  G-CSC, Goethe University Frankfurt
       3              :  * Authors: Andreas Vogel, Arne Naegel
       4              :  *
       5              :  * This file is part of UG4.
       6              :  *
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  *
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  *
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  *
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  *
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__DATA_EVALUATOR_IMPL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__DATA_EVALUATOR_IMPL__
      35              : 
      36              : namespace ug{
      37              : 
      38              : template <typename TDomain, typename TElemDisc>
      39            0 : DataEvaluatorBase<TDomain, TElemDisc>::
      40              : DataEvaluatorBase(int discPart,
      41              :               const std::vector<TElemDisc*>& vElemDisc,
      42              :               ConstSmartPtr<FunctionPattern> fctPat,
      43              :               const bool bNonRegularGrid,
      44              :               LocalVectorTimeSeries* pLocTimeSeries,
      45              :               const std::vector<number>* pvScaleMass,
      46              :               const std::vector<number>* pvScaleStiff)
      47            0 :    : m_spFctPattern(fctPat)
      48              : {
      49              : //      remember infos
      50            0 :         m_discPart = discPart;
      51            0 :         m_pLocTimeSeries = pLocTimeSeries;
      52            0 :         m_bNeedLocTimeSeries = false; // initially
      53            0 :         m_bUseHanging = false; // initially
      54              : 
      55            0 :         m_vElemDisc[PT_ALL] = vElemDisc;
      56              : 
      57              : //      create FunctionIndexMapping for each Disc
      58            0 :         for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
      59              :         {
      60              :         //      get elem disc
      61            0 :                 TElemDisc* disc = m_vElemDisc[PT_ALL][i];
      62              : 
      63              :         //      handle time dependency
      64            0 :                 if(pLocTimeSeries != NULL && pvScaleMass != NULL && pvScaleStiff != NULL){
      65            0 :                         disc->set_time_dependent(*pLocTimeSeries, *pvScaleMass, *pvScaleStiff);
      66              :                 }
      67            0 :                 else if(pLocTimeSeries != NULL){
      68            0 :                         disc->set_time_dependent(*pLocTimeSeries, std::vector<number>(), std::vector<number>());
      69              :                 }
      70              :                 else{
      71            0 :                         disc->set_time_independent();
      72              :                 }
      73              : 
      74              :         //      checks
      75            0 :                 disc->check_setup(bNonRegularGrid);
      76              : 
      77              :         //      cache time dependency
      78            0 :                 m_bNeedLocTimeSeries |= disc->local_time_series_needed();
      79              : 
      80              :         //      cache grid type required
      81            0 :                 if(bNonRegularGrid)
      82            0 :                         m_bUseHanging |= disc->use_hanging();
      83              : 
      84              :         //      sort by process type
      85              :                 ProcessType process;
      86              :                 if(!disc->is_time_dependent()) process = PT_STATIONARY;
      87              :                 else process = PT_INSTATIONARY;
      88            0 :                 m_vElemDisc[process].push_back(disc);
      89              :         }
      90            0 : }
      91              : 
      92              : 
      93              : ///////////////////////////////////////////////////////////////////////////////
      94              : // DataEvaluatorBase Setup
      95              : ///////////////////////////////////////////////////////////////////////////////
      96              : 
      97              : 
      98              : 
      99              : template <typename TDomain, typename TElemDisc>
     100            0 : void DataEvaluatorBase<TDomain, TElemDisc>::
     101              : add_data_to_eval_data(std::vector<SmartPtr<ICplUserData<dim> > >& vEvalData,
     102              :                       std::vector<SmartPtr<ICplUserData<dim> > >& vTryingToAdd)
     103              : {
     104              : //      if empty, we're done
     105            0 :         if(vTryingToAdd.empty()) return;
     106              : 
     107              : //      search for element in already scheduled data
     108              :         typename std::vector<SmartPtr<ICplUserData<dim> > >::iterator it, itEnd;
     109            0 :         it = find(vEvalData.begin(), vEvalData.end(), vTryingToAdd.back());
     110              : 
     111              : //      if found, skip this data
     112            0 :         if(it != vEvalData.end())
     113              :         {
     114              :                 vTryingToAdd.pop_back();
     115            0 :                 return;
     116              :         }
     117              : 
     118              : //      search if element already contained in list. Then, the element
     119              : //      did start the adding procedure before and a circle dependency
     120              : //      is found
     121              :         itEnd = vTryingToAdd.end(); itEnd--;
     122            0 :         it = find(vTryingToAdd.begin(), itEnd, *itEnd);
     123              : 
     124              : //      if found, return error of circle dependency
     125            0 :         if(it != itEnd)
     126            0 :                 UG_THROW("DataEvaluatorBase::add_data_to_eval_data:"
     127              :                                                 " Circle dependency of data detected for UserData.");
     128              : 
     129              : //      add all dependent datas
     130              :         SmartPtr<ICplUserData<dim> > data = vTryingToAdd.back();
     131            0 :         for(size_t i = 0; i < data->num_needed_data(); ++i)
     132              :         {
     133              :         //      add each data separately
     134            0 :                 vTryingToAdd.push_back(data->needed_data(i));
     135            0 :                 add_data_to_eval_data(vEvalData, vTryingToAdd);
     136              :         }
     137              : 
     138              : //      add this data to the evaluation list
     139            0 :         vEvalData.push_back(data);
     140              : 
     141              : //      pop last one, since now added to eval list
     142            0 :         if(!vTryingToAdd.empty())
     143              :                 vTryingToAdd.pop_back();
     144              : }
     145              : 
     146              : template <typename TDomain, typename TElemDisc>
     147            0 : void DataEvaluatorBase<TDomain, TElemDisc>::extract_imports_and_userdata(int subsetIndex, int discPart)
     148              : {
     149            0 :         clear_extracted_data_and_mappings();
     150              : 
     151              : //      queue for all user data needed
     152              :         std::vector<SmartPtr<ICplUserData<dim> > > vEvalData;
     153              :         std::vector<SmartPtr<ICplUserData<dim> > > vTryingToAdd;
     154              : 
     155              : //      In the next loop we extract all needed UserData:
     156              : //      We only process the DataImport if there has been set data to the import
     157              : //      since otherwise no evaluation is needed.
     158              : //      If there is data given, we get the connected UserData and add it to the vector
     159              : //      of EvaluationData. This simply adds the UserData to the queue for UserData, if
     160              : //      the data does not depend on other Data. But if the UserData itself has
     161              : //      dependencies to other UserData, this data is added first (in a recursive
     162              : //      process). Of course, no circle dependency between UserData is allowed.
     163              : 
     164              : //      In the same loop over the data imports, we schedule the DataImports for
     165              : //      evaluation and compute the correct FunctionMapping for the linearization
     166              : //      of the defect and the Data, the Import is connected to:
     167              : //      If the UserData does not depend on the primary unknowns, we're done. Else
     168              : //      we have to setup the Function mappings between the common function group
     169              : //      and the DataImport-FunctionGroup. This is simply the same function map as
     170              : //      for the element discretization, since the DataImport depends by definition
     171              : //      from and only from the primary variables of its associated IElemDisc.
     172              : 
     173              : //      loop elem discs
     174            0 :         for(size_t d = 0; d < m_vElemDisc[PT_ALL].size(); ++d)
     175              :         {
     176            0 :                 TElemDisc* disc = m_vElemDisc[PT_ALL][d];
     177              : 
     178              :         //      loop imports
     179            0 :                 for(size_t i = 0; i < disc->num_imports(); ++i)
     180              :                 {
     181              :                 //      get import
     182            0 :                         IDataImport<dim>* iimp = &(disc->get_import(i));
     183              : 
     184              :                 //      skip non-given data (no need for evaluation)
     185            0 :                         if(!iimp->data_given()) continue;
     186              : 
     187              :                 //      check part
     188            0 :                         if( !(iimp->part() & discPart) ) continue;
     189              : 
     190              :                 //      check correct process type
     191            0 :                         if(iimp->part() == MASS)
     192            0 :                                 if(!disc->is_time_dependent()) continue;
     193              : 
     194              :                 //      push export on stack of needed data
     195            0 :                         vTryingToAdd.push_back(iimp->data());
     196              : 
     197              :                 //      add data and all dependency to evaluation list
     198              :                         try{
     199            0 :                                 add_data_to_eval_data(vEvalData, vTryingToAdd);
     200              :                         }
     201            0 :                         UG_CATCH_THROW("DataEvaluatorBase:"
     202              :                                                 " Circle dependency of data detected for UserData.");
     203              : 
     204              :                 //      check that queue is empty now, else some internal error occured
     205            0 :                         if(!vTryingToAdd.empty())
     206            0 :                                 UG_THROW("DataEvaluatorBase:"
     207              :                                                 " Internal Error, UserData queue not empty after adding.");
     208              : 
     209              :                 //      done if and only if zero-derivative
     210            0 :                         if(iimp->zero_derivative()) continue;
     211              : 
     212              :                 //      remember Import
     213              :                         ProcessType process;
     214              :                         if(!disc->is_time_dependent()) process = PT_STATIONARY;
     215              :                         else process = PT_INSTATIONARY;
     216              : 
     217            0 :                         m_vImport[PT_ALL][iimp->part()].push_back(iimp);
     218            0 :                         m_vImport[process][iimp->part()].push_back(iimp);
     219              :                 }
     220              :         }
     221              : 
     222              : //      Now, we have processed all imports, that must be evaluated and have a long
     223              : //      vector of UserData that is connected to those imports. The UserData is already
     224              : //      sorted in this way: Data that depends on other data appears after the data
     225              : //      it depends on. This is important since we will schedule now the data for
     226              : //      evaluation and the data, that is needed by other data, will be computed
     227              : //      first. In addition, the data linker have to update their FunctionGroup and
     228              : //      must be sure that the data they depend on has already a correct FunctionGroup
     229              : //      set. This all is ensured by the (already produced) correct ordering.
     230              : //
     231              : //      In the next loop we process all UserData, that will be evaluated during
     232              : //      assembling (i.e. is connected to an Import). First, we check if the data
     233              : //      is constant. If so simply add it the the Constant Data vector; nothing more
     234              : //      has to be done here. Else we check if the data depends on the primary
     235              : //      unknowns. If this is not the case, the UserData must be a Position-dependent
     236              : //      data, but not constant. Thus, schedule it at the Position Data vector.
     237              : //      If the data depends on the primary unknowns we must proceed as follows:
     238              : //      First, we update the FunctionGroup of the Data, since it could be a linker
     239              : //      and having an incorrect FunctionGroup (iff the FunctionGroup of the data
     240              : //      the linker depends on has been changed). Then we create the function
     241              : //      mapping between the functions the linker depends on and the common Function
     242              : //      Group.
     243              : 
     244              : //      loop all needed user data and group it
     245            0 :         for(size_t i = 0; i < vEvalData.size(); ++i)
     246              :         {
     247              :         //      get the user data
     248              :                 SmartPtr<ICplUserData<dim> > ipData = vEvalData[i];
     249              : 
     250              :         //      update function pattern (this will update functionGroups and Map of Data)
     251              :                 try{
     252            0 :                         ipData->set_function_pattern(m_spFctPattern);
     253              :                 }
     254            0 :                 UG_CATCH_THROW("DataEvaluatorBase: Cannot set FunctionPattern to UserData.");
     255              : 
     256              :         //      sort data into const and non-solution dependent
     257            0 :                 if(ipData->constant()) {m_vConstData.push_back(ipData); continue;}
     258            0 :                 if(ipData->zero_derivative()){m_vPosData.push_back(ipData); continue;}
     259              : 
     260              :         //      save as dependent data
     261            0 :                 m_vDependentData.push_back(ipData);
     262              :         }
     263              : 
     264              : //      Handle time dependency
     265              : //      NOTE: constant data is not processed.
     266            0 :         if(m_pLocTimeSeries != NULL){
     267            0 :                 for(size_t i = 0; i < m_vPosData.size(); ++i)
     268            0 :                         m_vPosData[i]->set_times(m_pLocTimeSeries->times());
     269            0 :                 for(size_t i = 0; i < m_vDependentData.size(); ++i)
     270            0 :                         m_vDependentData[i]->set_times(m_pLocTimeSeries->times());
     271              :         }
     272              : 
     273              : //      NOTE: constant data is not processed, since constant == independent of si
     274            0 :         for(size_t i = 0; i < m_vPosData.size(); ++i)
     275              :                 m_vPosData[i]->set_subset(subsetIndex);
     276            0 :         for(size_t i = 0; i < m_vDependentData.size(); ++i)
     277              :                 m_vDependentData[i]->set_subset(subsetIndex);
     278            0 : }
     279              : 
     280              : template <typename TDomain, typename TElemDisc>
     281            0 : void DataEvaluatorBase<TDomain, TElemDisc>::clear_extracted_data_and_mappings()
     282              : {
     283            0 :         for(int type = 0; type < MAX_PROCESS; ++type){
     284              :                 m_vImport[type][MASS].clear();
     285              :                 m_vImport[type][STIFF].clear();
     286              :                 m_vImport[type][RHS].clear();
     287              :         }
     288              : 
     289              :         m_vConstData.clear();
     290              :         m_vPosData.clear();
     291              :         m_vDependentData.clear();
     292            0 : }
     293              : 
     294              : 
     295              : 
     296              : template <typename TDomain, typename TElemDisc>
     297            0 : void DataEvaluatorBase<TDomain, TElemDisc>::clear_positions_in_user_data()
     298              : {
     299              : //      remove ip series for all used UserData
     300            0 :         for(size_t i = 0; i < m_vConstData.size(); ++i) m_vConstData[i]->clear();
     301            0 :         for(size_t i = 0; i < m_vPosData.size(); ++i)   m_vPosData[i]->clear();
     302            0 :         for(size_t i = 0; i < m_vDependentData.size(); ++i) m_vDependentData[i]->clear();
     303            0 : }
     304              : 
     305              : 
     306              : ///////////////////////////////////////////////////////////////////////////////
     307              : // prepare / finish
     308              : ///////////////////////////////////////////////////////////////////////////////
     309              : 
     310              : template <typename TDomain, typename TElemDisc>
     311            0 : void DataEvaluatorBase<TDomain, TElemDisc>::set_time_point(const size_t timePoint)
     312              : {
     313            0 :         for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     314            0 :                 m_vElemDisc[PT_ALL][i]->set_time_point(timePoint);
     315              : 
     316              :         // NOTE: constant data is not processed.
     317            0 :         for(size_t i = 0; i < m_vPosData.size(); ++i)
     318              :                 m_vPosData[i]->set_time_point(timePoint);
     319            0 :         for(size_t i = 0; i < m_vDependentData.size(); ++i)
     320              :                 m_vDependentData[i]->set_time_point(timePoint);
     321            0 : }
     322              : 
     323              : 
     324              : 
     325              : ///////////////////////////////////////////////////////////////////////////////
     326              : // Error estimator's routines
     327              : ///////////////////////////////////////////////////////////////////////////////
     328              : 
     329              : template <typename TDomain, typename TElemDisc>
     330            0 : void DataEvaluatorBase<TDomain, TElemDisc>::
     331              : prepare_err_est_elem_loop(const ReferenceObjectID id, int si)
     332              : {
     333              : //      prepare loop (elem disc set local ip series here)
     334              :         try{
     335            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     336            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_err_est_elem_loop(id, si);
     337              :         }
     338            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_err_est_elem_loop: "
     339              :                                                 "Cannot prepare element loop.");
     340              : 
     341              : //      extract data imports and user data
     342              :         try{
     343            0 :                 extract_imports_and_userdata(si, m_discPart);
     344              :         }
     345            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_err_est_elem_loop: "
     346              :                                         "Cannot extract imports and userdata.");
     347              : 
     348              : //      check setup of imports
     349              :         try{
     350            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][MASS].size(); ++i)
     351            0 :                         m_vImport[PT_ALL][MASS][i]->check_setup();
     352            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][STIFF].size(); ++i)
     353            0 :                         m_vImport[PT_ALL][STIFF][i]->check_setup();
     354            0 :                 for(size_t i = 0; i < m_vImport[PT_ALL][RHS].size(); ++i)
     355            0 :                         m_vImport[PT_ALL][RHS][i]->check_setup();
     356              :         }
     357            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_err_est_elem_loop: Import not correctly implemented.");
     358              : 
     359              : //      prepare and check dependent data
     360              :         try{
     361            0 :                 for(size_t i = 0; i < m_vDependentData.size(); ++i){
     362            0 :                         m_vDependentData[i]->check_setup();
     363              :                 }
     364              :         }
     365            0 :         UG_CATCH_THROW("DataEvaluatorBase::prepare_err_est_elem_loop: Dependent UserData "
     366              :                                    " (e.g. Linker or Export) is not ready for evaluation.");
     367              : 
     368              : //      evaluate constant data
     369            0 :         for(size_t i = 0; i < m_vConstData.size(); ++i)
     370            0 :                 m_vConstData[i]->compute((LocalVector*)NULL, NULL, NULL, false);
     371            0 : }
     372              : 
     373              : template <typename TDomain, typename TElemDisc>
     374            0 : void DataEvaluatorBase<TDomain, TElemDisc>::finish_err_est_elem_loop()
     375              : {
     376              : //      finish each elem error estimator disc
     377              :         try{
     378            0 :                 for(size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     379            0 :                         m_vElemDisc[PT_ALL][i]->do_fsh_err_est_elem_loop();
     380              :         }
     381            0 :         UG_CATCH_THROW("DataEvaluatorBase::finish_err_est_elem_loop: Cannot finish error estimator element loop");
     382              : 
     383              : //      clear positions at user data
     384            0 :         clear_positions_in_user_data();
     385            0 : }
     386              : 
     387              : template <typename TDomain, typename TElemDisc>
     388            0 : void DataEvaluatorBase<TDomain, TElemDisc>::prepare_err_est_elem
     389              : (LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[],
     390              : const LocalIndices& ind, bool bDeriv)
     391              : {
     392              :         try
     393              :         {
     394            0 :                 for (size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     395            0 :                         m_vElemDisc[PT_ALL][i]->do_prep_err_est_elem(u, elem, vCornerCoords);
     396              :         }
     397            0 :         UG_CATCH_THROW("DataEvaluatorBase::compute_elem_err_est: Cannot prepare element.");
     398              : 
     399              : //      evaluate position data
     400            0 :         for (size_t i = 0; i < m_vPosData.size(); ++i)
     401            0 :                 m_vPosData[i]->compute(&u, elem, vCornerCoords, false);
     402              : 
     403              : //      process dependent data:
     404              : //      We can not simply compute exports first, then Linker, because an export
     405              : //      itself could depend on other data if implemented somehow in the IElemDisc
     406              : //      (e.g. using data from some DataImport). Thus, we have to loop the sorted
     407              : //      vector of all dependent data (that is correctly sorted the way that always
     408              : //      needed data has previously computed).
     409              : 
     410              : //      compute the data
     411              :         try
     412              :         {
     413            0 :                 for (size_t i = 0; i < m_vDependentData.size(); ++i)
     414              :                 {
     415            0 :                         u.access_by_map(m_vDependentData[i]->map());
     416            0 :                         m_vDependentData[i]->compute(&u, elem, vCornerCoords, false);
     417              :                 }
     418              :         }
     419            0 :         UG_CATCH_THROW("DataEvaluatorBase::compute_elem_err_est: Cannot compute data for Export or Linker.");
     420            0 : }
     421              : 
     422              : 
     423              : template <typename TDomain, typename TElemDisc>
     424            0 : void DataEvaluatorBase<TDomain, TElemDisc>::
     425              : compute_err_est_A_elem
     426              : (       LocalVector& u,
     427              :         GridObject* elem,
     428              :         const MathVector<dim> vCornerCoords[],
     429              :         const LocalIndices& ind,
     430              :         const number scaleMass,
     431              :         const number scaleStiff)
     432              : {
     433              :         UG_ASSERT(m_discPart & STIFF, "Using compute_err_est_A_elem, but not STIFF requested.");
     434              :         try
     435              :         {
     436            0 :                 for (std::size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     437            0 :                         m_vElemDisc[PT_ALL][i]->do_compute_err_est_A_elem(u, elem, vCornerCoords, scaleStiff);
     438              :         }
     439            0 :         UG_CATCH_THROW("DataEvaluatorBase::compute_err_est_A_elem: Cannot assemble stiffness part of error estimator");
     440            0 : }
     441              : 
     442              : template <typename TDomain, typename TElemDisc>
     443            0 : void DataEvaluatorBase<TDomain, TElemDisc>::
     444              : compute_err_est_M_elem
     445              : (       LocalVector& u,
     446              :         GridObject* elem,
     447              :         const MathVector<dim> vCornerCoords[],
     448              :         const LocalIndices& ind,
     449              :         const number scaleMass,
     450              :         const number scaleStiff)
     451              : {
     452              :         UG_ASSERT(m_discPart & MASS, "Using compute_err_est_M_elem, but not MASS requested.");
     453              :         try
     454              :         {
     455            0 :                 for (std::size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     456            0 :                         m_vElemDisc[PT_ALL][i]->do_compute_err_est_M_elem(u, elem, vCornerCoords, scaleMass);
     457              :         }
     458            0 :         UG_CATCH_THROW("DataEvaluatorBase::compute_err_est_A_elem: Cannot assemble stiffness part of error estimator");
     459            0 : }
     460              : 
     461              : template <typename TDomain, typename TElemDisc>
     462            0 : void DataEvaluatorBase<TDomain, TElemDisc>::
     463              : compute_err_est_rhs_elem
     464              : (       GridObject* elem,
     465              :         const MathVector<dim> vCornerCoords[],
     466              :         const LocalIndices& ind,
     467              :         const number scaleMass,
     468              :         const number scaleStiff)
     469              : {
     470              :         UG_ASSERT(m_discPart & RHS, "Using compute_err_est_rhs_elem, but not RHS requested.");
     471              :         try
     472              :         {
     473            0 :                 for (std::size_t i = 0; i < m_vElemDisc[PT_ALL].size(); ++i)
     474            0 :                         m_vElemDisc[PT_ALL][i]->do_compute_err_est_rhs_elem(elem, vCornerCoords, scaleStiff);
     475              :         }
     476            0 :         UG_CATCH_THROW("DataEvaluatorBase::compute_err_est_rhs_elem: Cannot assemble rhs part of error estimator");
     477            0 : }
     478              : 
     479              : 
     480              : } // namespace ug
     481              : 
     482              : 
     483              : #endif
        

Generated by: LCOV version 2.0-1