LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/user_data - user_data_impl.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 151 0
Test Date: 2026-09-23 08:42:13 Functions: 0.0 % 289 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-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__SPATIAL_DISC__USER_DATA__USER_DATA_IMPL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__USER_DATA_IMPL__
      35              : 
      36              : #include "user_data.h"
      37              : #include "lib_disc/common/groups_util.h"
      38              : 
      39              : namespace ug{
      40              : 
      41              : ////////////////////////////////////////////////////////////////////////////////
      42              : //      ICplUserData
      43              : ////////////////////////////////////////////////////////////////////////////////
      44              : 
      45              : template <int dim>
      46            0 : ICplUserData<dim>::ICplUserData()
      47            0 : :       m_locPosDim(-1), m_timePoint(0), m_defaultTimePoint(-1), m_si(-1)
      48              : {
      49              :         m_vNumIP.clear();
      50              :         m_vMayChange.clear();
      51              :         m_pvLocIP1d.clear(); m_pvLocIP2d.clear(); m_pvLocIP3d.clear();
      52            0 :         m_vTime.clear(); m_vTime.push_back(0.0);
      53            0 : }
      54              : 
      55              : template <int dim>
      56            0 : void ICplUserData<dim>::clear()
      57              : {
      58            0 :         local_ip_series_to_be_cleared();
      59              :         m_vNumIP.clear();
      60              :         m_vMayChange.clear();
      61            0 :         m_locPosDim = -1;
      62              :         m_pvLocIP1d.clear(); m_pvLocIP2d.clear(); m_pvLocIP3d.clear();
      63            0 :         m_timePoint = 0;
      64            0 :         m_vTime.clear(); m_vTime.push_back(0.0);
      65            0 :         m_si = -1;
      66            0 : }
      67              : 
      68              : template <int dim>
      69              : template <int ldim>
      70            0 : size_t ICplUserData<dim>::register_local_ip_series(const MathVector<ldim>* vPos,
      71              :                                          const size_t numIP,
      72              :                                          const int timePointSpec,
      73              :                                          bool bMayChange)
      74              : {
      75              : //      check, that dimension is ok.
      76            0 :         if(m_locPosDim == -1) m_locPosDim = ldim;
      77            0 :         else if(m_locPosDim != ldim)
      78            0 :                 UG_THROW("Local IP dimension conflict");
      79              :         
      80              : //      get the "right" time point specification
      81            0 :         int theTimePoint = (m_defaultTimePoint >= 0)? m_defaultTimePoint : timePointSpec;
      82              : 
      83              : //      get local positions
      84              :         std::vector<const MathVector<ldim>*>& vvIP = get_local_ips(Int2Type<ldim>());
      85              : 
      86              : //      search for ips
      87              : //      we only identify ip series if the local ip positions will not change
      88            0 :         if(!bMayChange && numIP != 0)
      89            0 :                 for(size_t s = 0; s < vvIP.size(); ++s)
      90              :                 {
      91              :                 //      return series number iff exists and local ips remain constant
      92            0 :                         if(!m_vMayChange[s])
      93            0 :                                 if(vvIP[s] == vPos && m_vNumIP[s] == numIP && m_vTimePoint[s] == theTimePoint)
      94            0 :                                         return s;
      95              :                 }
      96              : 
      97              : //      if series not yet registered, add it
      98            0 :         vvIP.push_back(vPos);
      99            0 :         m_vNumIP.push_back(numIP);
     100            0 :         m_vTimePoint.push_back(theTimePoint);
     101            0 :         m_vMayChange.push_back(bMayChange);
     102              : 
     103              : //      invoke callback:
     104              : //      This callback is called, whenever the local_ip_series have changed. It
     105              : //      allows derived classes to react on this changes. For example, the data
     106              : //      linker must himself request local_ip_series from the data inputs of
     107              : //      the linker. In addition value fields and derivative fields must be adjusted
     108              : //      in UserData<TData, dim> etc.
     109            0 :         local_ip_series_added(m_vNumIP.size() - 1);
     110              : 
     111              : //      return new series id
     112            0 :         return m_vNumIP.size() - 1;
     113              : }
     114              : 
     115              : 
     116              : template <int dim>
     117              : template <int ldim>
     118            0 : void ICplUserData<dim>::set_local_ips(const size_t seriesID,
     119              :                             const MathVector<ldim>* vPos,
     120              :                             const size_t numIP)
     121              : {
     122              : //      check series id
     123            0 :         if(seriesID >= num_series())
     124            0 :                 UG_THROW("Trying to set new ips for invalid seriesID "<<seriesID);
     125              : 
     126              : //      check that series is changeable
     127            0 :         if(!m_vMayChange[seriesID])
     128            0 :                 UG_THROW("Local IP is not changable, but trying to set new ips.");
     129              : 
     130              : //      check, that dimension is ok.
     131            0 :         if(m_locPosDim == -1) m_locPosDim = ldim;
     132            0 :         else if(m_locPosDim != ldim)
     133            0 :                 UG_THROW("Local IP dimension conflict");
     134              : 
     135              : //      get local positions
     136              :         std::vector<const MathVector<ldim>*>& vvIP = get_local_ips(Int2Type<ldim>());
     137              : 
     138              : //      check if still at same position and with same numIP. In that case the
     139              : //      positions have not changed. We have nothing to do
     140            0 :         if(vvIP[seriesID] == vPos && m_vNumIP[seriesID] == numIP) return;
     141              : 
     142              : //      remember new positions and numIP
     143            0 :         vvIP[seriesID] = vPos;
     144            0 :         m_vNumIP[seriesID] = numIP;
     145              : 
     146              : //      invoke callback:
     147              : //      This callback is called, whenever the local_ip_series have changed. It
     148              : //      allows derived classes to react on this changes. For example, the data
     149              : //      linker must himself request local_ip_series from the data inputs of
     150              : //      the linker. In addition value fields and derivative fields must be adjusted
     151              : //      in UserData<TData, dim> etc.
     152            0 :         local_ips_changed(seriesID, numIP);
     153              : }
     154              : 
     155              : template <int dim>
     156            0 : void ICplUserData<dim>::set_time_point(const size_t seriesID,
     157              :                                         const int timePointSpec)
     158              : {
     159              : //      check series id
     160            0 :         if(seriesID >= num_series())
     161            0 :                 UG_THROW("Trying to set new ips for invalid seriesID "<<seriesID);
     162              : 
     163              : //      check that series is changeable
     164            0 :         if(!m_vMayChange[seriesID])
     165            0 :                 UG_THROW("Time point specification is not changable, but trying to set a new one.");
     166              :         
     167              : //      set the new time point specification (if it is not prescribed by the object)
     168            0 :         m_vTimePoint[seriesID] = (m_defaultTimePoint >= 0)? m_defaultTimePoint : timePointSpec;
     169              :         
     170              : //TODO: Should we call the callback here? (No data sizes are changed!)
     171            0 : }
     172              : 
     173              : template <int dim>
     174              : template <int ldim>
     175            0 : const MathVector<ldim>* ICplUserData<dim>::local_ips(size_t s) const
     176              : {
     177              : //      check, that dimension is ok.
     178            0 :         if(m_locPosDim != ldim) UG_THROW("Local IP dimension conflict");
     179              : 
     180              :         UG_ASSERT(s < num_series(), "Wrong series id");
     181              : 
     182              : //      NOTE: local ips may be NULL, if no ip position given, i.e. num_ip(s) == 0
     183            0 :         return get_local_ips(Int2Type<ldim>())[s];
     184              : }
     185              : 
     186              : template <int dim>
     187              : template <int ldim>
     188              : const MathVector<ldim>& ICplUserData<dim>::local_ip(size_t s, size_t ip) const
     189              : {
     190              : //      check, that dimension is ok.
     191              :         if(m_locPosDim != ldim) UG_THROW("Local IP dimension conflict");
     192              : 
     193              :         UG_ASSERT(s < num_series(), "Wrong series id");
     194              :         UG_ASSERT(ip < num_ip(s), "Invalid index.");
     195              : 
     196              :         return get_local_ips(Int2Type<ldim>())[s][ip];
     197              : }
     198              : 
     199              : template <int dim>
     200              : int ICplUserData<dim>::time_point_specification(size_t s) const
     201              : {
     202              :         UG_ASSERT(s < num_series(), "Wrong series id");
     203              : 
     204              :         return m_vTimePoint[s];
     205              : }
     206              : 
     207              : template <int dim>
     208              : size_t ICplUserData<dim>::time_point(size_t s) const
     209              : {
     210              :         UG_ASSERT(s < num_series(), "Wrong series id:" << s << ">=" << num_series());
     211              : 
     212              : //      size_t time_spec;
     213              : //      if ((time_spec = m_vTimePoint[s]) >= 0)
     214            0 :         if (m_vTimePoint[s] >= 0)
     215            0 :                 return m_vTimePoint[s];
     216            0 :         return m_timePoint;
     217              : }
     218              : 
     219              : template <int dim>
     220              : bool ICplUserData<dim>::at_current_time(size_t s) const
     221              : {
     222              :         UG_ASSERT(s < num_series(), "Wrong series id:" << s << ">=" << num_series());
     223              :         
     224              :         int time_spec;
     225            0 :         if ((time_spec = m_vTimePoint[s]) >= 0)
     226            0 :                 return ((size_t) time_spec) == m_timePoint;
     227              :         return true;
     228              : }
     229              : 
     230              : template <int dim>
     231            0 : void ICplUserData<dim>::set_global_ips(size_t s, const MathVector<dim>* vPos, size_t numIP)
     232              : {
     233              :         UG_ASSERT(s < num_series(), "Wrong series id: "<<s<<" (numSeries: "<<num_series()<<")");
     234              : 
     235              : //      check number of ips (must match local ip number)
     236            0 :         if(numIP != num_ip(s))
     237            0 :                 UG_THROW("UserData::set_global_ips: Num Local IPs is " << num_ip(s)
     238              :                                << ", but trying to set Num Global IPs: " << numIP <<
     239              :                                " for series "<< s);
     240              : 
     241              : //      remember global positions
     242            0 :         m_vvGlobPos[s] = vPos;
     243              : 
     244              : //      invoke callback:
     245              : //      this callback is called every time the global position changes. It gives
     246              : //      derived classes the possibility to react on this fact. E.g. the data
     247              : //      linker must forward the global positions to its own imports.
     248            0 :         global_ips_changed(s, vPos, numIP);
     249            0 : }
     250              : 
     251              : template <int dim>
     252              : inline void ICplUserData<dim>::check_s(size_t s) const
     253              : {
     254              :         UG_ASSERT(s < num_series(), "Wrong series id");
     255              :         UG_ASSERT(s < m_vvGlobPos.size(), "Invalid index.");
     256              : }
     257              : 
     258              : template <int dim>
     259              : inline void ICplUserData<dim>::check_s_ip(size_t s, size_t ip) const
     260              : {
     261              :         check_s(s);
     262              :         UG_ASSERT(ip < num_ip(s), "Invalid index.");
     263              :         UG_ASSERT(m_vvGlobPos[s] != NULL, "Global IP not set.");
     264              : }
     265              : 
     266              : ////////////////////////////////////////////////////////////////////////////////
     267              : //      UserData
     268              : ////////////////////////////////////////////////////////////////////////////////
     269              : 
     270              : template <typename TData, int dim, typename TRet>
     271            0 : void CplUserData<TData,dim,TRet>::
     272              : register_storage_callback(DataImport<TData,dim>* obj, void (DataImport<TData,dim>::*func)())
     273              : {
     274              :         typedef std::pair<DataImport<TData,dim>*, CallbackFct> Pair;
     275              :         //      m_vCallback.push_back(Pair(obj,func));
     276            0 :         m_vCallback.push_back(Pair(obj, std::bind(func, obj)));
     277            0 : }
     278              : 
     279              : template <typename TData, int dim, typename TRet>
     280            0 : void CplUserData<TData,dim,TRet>::
     281              : unregister_storage_callback(DataImport<TData,dim>* obj)
     282              : {
     283              :         typedef typename std::vector<std::pair<DataImport<TData,dim>*, CallbackFct> > VecType;
     284              :         typedef typename VecType::iterator iterator;
     285              :         iterator iter = m_vCallback.begin();
     286            0 :         while(iter != m_vCallback.end())
     287              :         {
     288            0 :                 if((*iter).first == obj) iter = m_vCallback.erase(iter);
     289              :                 else ++iter;
     290              :         }
     291            0 : }
     292              : 
     293              : template <typename TData, int dim, typename TRet>
     294            0 : void CplUserData<TData,dim,TRet>::
     295              : call_storage_callback() const
     296              : {
     297              :         typedef typename std::vector<std::pair<DataImport<TData,dim>*, CallbackFct> > VecType;
     298              :         typedef typename VecType::const_iterator iterator;
     299            0 :         for(iterator iter = m_vCallback.begin(); iter != m_vCallback.end(); ++iter)
     300              :         {
     301              :                 //              (((*iter).first)->*((*iter).second))();
     302              :                 ((*iter).second)();
     303              :         }
     304            0 : }
     305              : 
     306              : template <typename TData, int dim, typename TRet>
     307              : inline void CplUserData<TData,dim,TRet>::check_series(size_t s) const
     308              : {
     309              :         UG_ASSERT(s < num_series(), "Wrong series id"<<s);
     310              :         UG_ASSERT(s < m_vvValue.size(), "Invalid index "<<s);
     311              : }
     312              : 
     313              : template <typename TData, int dim, typename TRet>
     314              : inline void CplUserData<TData,dim,TRet>::check_series_ip(size_t s, size_t ip) const
     315              : {
     316              :         check_series(s);
     317              :         UG_ASSERT(ip < num_ip(s), "Invalid index "<<ip);
     318              :         UG_ASSERT(ip < m_vvValue[s].size(), "Invalid index "<<ip);
     319              : }
     320              : 
     321              : template <typename TData, int dim, typename TRet>
     322            0 : void CplUserData<TData,dim,TRet>::local_ip_series_added(const size_t seriesID)
     323              : {
     324              :         const size_t s = seriesID;
     325              : 
     326              : //      check, that only increasing the data, this is important to guarantee,
     327              : //      that the allocated memory pointer remain valid. They are used outside of
     328              : //      the class as well to allow fast access to the data.
     329            0 :         if(s < m_vvValue.size())
     330            0 :                 UG_THROW("Decrease is not implemented. Series: "<<s<<
     331              :                                          ", currNumSeries: "<<m_vvValue.size());
     332              : 
     333              : //      increase number of series if needed
     334            0 :         m_vvValue.resize(s+1);
     335            0 :         m_vvBoolFlag.resize(s+1);
     336              : 
     337              : //      allocate new storage
     338            0 :         m_vvValue[s].resize(num_ip(s));
     339            0 :         m_vvBoolFlag[s].resize(num_ip(s), true);
     340            0 :         value_storage_changed(s);
     341            0 :         call_storage_callback();
     342              : 
     343              : //      call base class callback
     344              :         base_type::local_ip_series_added(seriesID);
     345            0 : }
     346              : 
     347              : template <typename TData, int dim, typename TRet>
     348            0 : void CplUserData<TData,dim,TRet>::local_ip_series_to_be_cleared()
     349              : {
     350              : //      free the memory
     351              : //      clear all series
     352              :         m_vvValue.clear();
     353              :         m_vvBoolFlag.clear();
     354              : 
     355              : //      call base class callback (if implementation given)
     356              : //      base_type::local_ip_series_to_be_cleared();
     357            0 : }
     358              : 
     359              : template <typename TData, int dim, typename TRet>
     360            0 : void CplUserData<TData,dim,TRet>::local_ips_changed(const size_t seriesID, const size_t newNumIP)
     361              : {
     362              : //      resize only when more data is needed than actually allocated
     363            0 :         if(newNumIP >= m_vvValue[seriesID].size())
     364              :         {
     365              :         //      resize
     366            0 :                 m_vvValue[seriesID].resize(newNumIP);
     367            0 :                 m_vvBoolFlag[seriesID].resize(newNumIP, true);
     368              : 
     369              :         //      invoke callback
     370            0 :                 value_storage_changed(seriesID);
     371            0 :                 call_storage_callback();
     372              :         }
     373              : 
     374              : //      call base class callback (if implementation given)
     375              : //      base_type::local_ips_changed(seriesID);
     376            0 : }
     377              : 
     378              : ////////////////////////////////////////////////////////////////////////////////
     379              : //      DependentUserData
     380              : ////////////////////////////////////////////////////////////////////////////////
     381              : 
     382              : template <typename TData, int dim>
     383            0 : void DependentUserData<TData,dim>::set_function_pattern(ConstSmartPtr<FunctionPattern> fctPatt)
     384              : {
     385            0 :         this->m_fctGrp.set_function_pattern(fctPatt);
     386            0 :         extract_fct_grp();
     387            0 : }
     388              : 
     389              : template <typename TData, int dim>
     390            0 : void DependentUserData<TData,dim>::set_functions(const char* symbFct)
     391              : {
     392            0 :         set_functions(std::string(symbFct));
     393            0 : }
     394              : 
     395              : template <typename TData, int dim>
     396            0 : void DependentUserData<TData,dim>::set_functions(const std::string& symbFct)
     397              : {
     398            0 :         set_functions(TokenizeTrimString(symbFct));
     399            0 : }
     400              : 
     401              : template <typename TData, int dim>
     402              : void DependentUserData<TData,dim>::set_functions(const std::vector<std::string>& symbFct)
     403              : {
     404            0 :         m_SymbFct = symbFct;
     405            0 :         extract_fct_grp();
     406            0 : }
     407              : 
     408              : template <typename TData, int dim>
     409            0 : void DependentUserData<TData,dim>::extract_fct_grp()
     410              : {
     411              :         //      if associated infos missing return
     412            0 :         ConstSmartPtr<FunctionPattern> spFctPatt = this->m_fctGrp.function_pattern();
     413            0 :         if(spFctPatt.invalid()) return;
     414              : 
     415              :         //      if no function passed, clear functions
     416            0 :         if(m_SymbFct.size() == 1 && m_SymbFct[0].empty()) m_SymbFct.clear();
     417              : 
     418              :         //      if functions passed with separator, but not all tokens filled, throw error
     419            0 :         for(size_t i = 0; i < m_SymbFct.size(); ++i)
     420              :         {
     421            0 :                 if(m_SymbFct.empty())
     422            0 :                         UG_THROW("Error while setting functions in a DependentUserData: passed "
     423              :                                         "function string lacks a "
     424              :                                         "function specification at position "<<i<<"(of "
     425              :                                         <<m_SymbFct.size()-1<<")");
     426              :         }
     427              : 
     428            0 :         if(m_SymbFct.empty()){
     429            0 :                 this->m_fctGrp.clear();
     430            0 :                 return;
     431              :         }
     432              : 
     433              :         //      create function group of this elem disc
     434              :         try{
     435            0 :                 this->m_fctGrp.clear();
     436            0 :                 this->m_fctGrp.add(m_SymbFct);
     437            0 :         }UG_CATCH_THROW("DependentUserData: Cannot find some symbolic function "
     438              :                         "name.");
     439              : 
     440              :         //      create a mapping between all functions and the function group of this
     441              :         //      element disc.
     442              :         try{
     443            0 :                 CreateFunctionIndexMapping(this->m_map, this->m_fctGrp, spFctPatt);
     444            0 :         }UG_CATCH_THROW("DependentUserData: Cannot create Function Index Mapping.");
     445              : 
     446            0 :         this->check_setup();
     447              : }
     448              : 
     449              : template <typename TData, int dim>
     450            0 : void DependentUserData<TData,dim>::update_dof_sizes(const LocalIndices& ind)
     451              : {
     452              : //      check size
     453            0 :         const FunctionIndexMapping& map = this->map();
     454              :         UG_ASSERT(map.num_fct() == this->num_fct(), "Number function mismatch.");
     455              : 
     456              : //      cache numFct and their numDoFs
     457            0 :         m_vvNumDoFPerFct.resize(map.num_fct());
     458            0 :         for(size_t fct = 0; fct < m_vvNumDoFPerFct.size(); ++fct)
     459            0 :                 m_vvNumDoFPerFct[fct] = ind.num_dof(map[fct]);
     460              : 
     461              :         resize_deriv_array();
     462            0 : }
     463              : 
     464              : template <typename TData, int dim>
     465              : void DependentUserData<TData,dim>::resize_deriv_array()
     466              : {
     467              : //      resize num fct
     468            0 :         for(size_t s = 0; s < m_vvvvDeriv.size(); ++s)
     469            0 :                 resize_deriv_array(s);
     470              : }
     471              : 
     472              : template <typename TData, int dim>
     473            0 : void DependentUserData<TData,dim>::resize_deriv_array(const size_t s)
     474              : {
     475              : //      resize ips
     476            0 :         m_vvvvDeriv[s].resize(num_ip(s));
     477              : 
     478            0 :         for(size_t ip = 0; ip < m_vvvvDeriv[s].size(); ++ip)
     479              :         {
     480              :         //      resize num fct
     481            0 :                 m_vvvvDeriv[s][ip].resize(m_vvNumDoFPerFct.size());
     482              : 
     483              :         //      resize dofs
     484            0 :                 for(size_t fct = 0; fct < m_vvNumDoFPerFct.size(); ++fct)
     485            0 :                         m_vvvvDeriv[s][ip][fct].resize(m_vvNumDoFPerFct[fct]);
     486              :         }
     487            0 : }
     488              : 
     489              : template <typename TData, int dim>
     490            0 : void DependentUserData<TData,dim>::set_zero(std::vector<std::vector<TData> > vvvDeriv[], const size_t nip)
     491              : {
     492            0 :         for(size_t ip = 0; ip < nip; ++ip)
     493            0 :                 for(size_t fct = 0; fct <  vvvDeriv[ip].size(); ++fct)
     494            0 :                         for(size_t sh = 0; sh <  vvvDeriv[ip][fct].size(); ++sh)
     495              :                         {
     496            0 :                                 vvvDeriv[ip][fct][sh] = 0.0;
     497              :                         }
     498            0 : }
     499              : 
     500              : template <typename TData, int dim>
     501              : inline void DependentUserData<TData,dim>::check_s_ip(size_t s, size_t ip) const
     502              : {
     503              :         UG_ASSERT(s < this->num_series(), "Wrong series id"<<s);
     504              :         UG_ASSERT(s < m_vvvvDeriv.size(), "Invalid index "<<s);
     505              :         UG_ASSERT(ip < this->num_ip(s), "Invalid index "<<ip);
     506              :         UG_ASSERT(ip < m_vvvvDeriv[s].size(), "Invalid index "<<ip);
     507              : }
     508              : 
     509              : template <typename TData, int dim>
     510              : inline void DependentUserData<TData,dim>::check_s_ip_fct(size_t s, size_t ip, size_t fct) const
     511              : {
     512              :         check_s_ip(s,ip);
     513              :         UG_ASSERT(fct < m_vvvvDeriv[s][ip].size(), "Invalid index.");
     514              : }
     515              : 
     516              : template <typename TData, int dim>
     517              : inline void DependentUserData<TData,dim>::check_s_ip_fct_dof(size_t s, size_t ip, size_t fct, size_t dof) const
     518              : {
     519              :         check_s_ip_fct(s,ip,fct);
     520              :         UG_ASSERT(dof < m_vvvvDeriv[s][ip][fct].size(), "Invalid index.");
     521              : }
     522              : 
     523              : template <typename TData, int dim>
     524            0 : void DependentUserData<TData,dim>::local_ip_series_added(const size_t seriesID)
     525              : {
     526              : //      adjust data arrays
     527            0 :         m_vvvvDeriv.resize(seriesID+1);
     528              : 
     529              : //      forward change signal to base class
     530            0 :         base_type::local_ip_series_added(seriesID);
     531            0 : }
     532              : 
     533              : template <typename TData, int dim>
     534            0 : void DependentUserData<TData,dim>::local_ip_series_to_be_cleared()
     535              : {
     536              : //      adjust data arrays
     537              :         m_vvvvDeriv.clear();
     538              : 
     539              : //      forward change signal to base class
     540            0 :         base_type::local_ip_series_to_be_cleared();
     541            0 : }
     542              : 
     543              : template <typename TData, int dim>
     544            0 : void DependentUserData<TData,dim>::local_ips_changed(const size_t seriesID, const size_t newNumIP)
     545              : {
     546              :         UG_ASSERT(seriesID < m_vvvvDeriv.size(), "wrong series id.");
     547              : 
     548              : //      resize only when more data is needed than actually allocated
     549            0 :         if(newNumIP >= m_vvvvDeriv[seriesID].size())
     550            0 :                 resize_deriv_array(seriesID);
     551              : 
     552              : //      call base class callback (if implementation given)
     553            0 :         base_type::local_ips_changed(seriesID, newNumIP);
     554            0 : }
     555              : 
     556              : } // end namespace ug
     557              : 
     558              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__USER_DATA__USER_DATA_IMPL__ */
        

Generated by: LCOV version 2.0-1