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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__LAGRANGE_DIRICHLET_BOUNDARY_IMPL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__LAGRANGE_DIRICHLET_BOUNDARY_IMPL__
      35              : 
      36              : #include "lagrange_dirichlet_boundary.h"
      37              : #include "lib_disc/function_spaces/grid_function.h"
      38              : #include "lib_disc/function_spaces/dof_position_util.h"
      39              : 
      40              : #ifdef UG_FOR_LUA
      41              : #include "bindings/lua/lua_user_data.h"
      42              : #endif
      43              : 
      44              : namespace ug{
      45              : 
      46              : 
      47              : ////////////////////////////////////////////////////////////////////////////////
      48              : //      setup
      49              : ////////////////////////////////////////////////////////////////////////////////
      50              : 
      51              : template <typename TDomain, typename TAlgebra>
      52            0 : void DirichletBoundary<TDomain, TAlgebra>::
      53              : set_approximation_space(SmartPtr<ApproximationSpace<TDomain> > approxSpace)
      54              : {
      55            0 :         base_type::set_approximation_space(approxSpace);
      56            0 :         m_spApproxSpace = approxSpace;
      57            0 :         m_spDomain = approxSpace->domain();
      58            0 :         m_aaPos = m_spDomain->position_accessor();
      59            0 : }
      60              : 
      61              : template <typename TDomain, typename TAlgebra>
      62            0 : void DirichletBoundary<TDomain, TAlgebra>::
      63              : clear()
      64              : {
      65              :         m_vBNDNumberData.clear();
      66              :         m_vNumberData.clear();
      67              :         m_vConstNumberData.clear();
      68              :         m_vVectorData.clear();
      69            0 : }
      70              : 
      71              : template <typename TDomain, typename TAlgebra>
      72            0 : void DirichletBoundary<TDomain, TAlgebra>::
      73              : add(SmartPtr<UserData<number, dim, bool> > func, const char* function, const char* subsets)
      74              : {
      75            0 :         m_vBNDNumberData.push_back(CondNumberData(func, function, subsets));
      76            0 : }
      77              : 
      78              : template <typename TDomain, typename TAlgebra>
      79            0 : void DirichletBoundary<TDomain, TAlgebra>::
      80              : add(SmartPtr<UserData<number, dim, bool> > func, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
      81              : {
      82              :         std::string function;
      83            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
      84            0 :                 if(i > 0) function.append(",");
      85              :                 function.append(Fcts[i]);
      86              :         }
      87              :         std::string subsets;
      88            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
      89            0 :                 if(i > 0) subsets.append(",");
      90              :                 subsets.append(Subsets[i]);
      91              :         }
      92              : 
      93            0 :         add(func, function.c_str(), subsets.c_str());
      94            0 : }
      95              : 
      96              : template <typename TDomain, typename TAlgebra>
      97            0 : void DirichletBoundary<TDomain, TAlgebra>::
      98              : add(SmartPtr<UserData<number, dim> > func, const char* function, const char* subsets)
      99              : {
     100            0 :         m_vNumberData.push_back(NumberData(func, function, subsets));
     101            0 : }
     102              : 
     103              : template <typename TDomain, typename TAlgebra>
     104            0 : void DirichletBoundary<TDomain, TAlgebra>::
     105              : add(SmartPtr<UserData<number, dim> > func, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     106              : {
     107              :         std::string function;
     108            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     109            0 :                 if(i > 0) function.append(",");
     110              :                 function.append(Fcts[i]);
     111              :         }
     112              :         std::string subsets;
     113            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     114            0 :                 if(i > 0) subsets.append(",");
     115              :                 subsets.append(Subsets[i]);
     116              :         }
     117              : 
     118            0 :         add(func, function.c_str(), subsets.c_str());
     119            0 : }
     120              : 
     121              : template <typename TDomain, typename TAlgebra>
     122            0 : void DirichletBoundary<TDomain, TAlgebra>::
     123              : add(number value, const char* function, const char* subsets)
     124              : {
     125            0 :         m_vConstNumberData.push_back(ConstNumberData(value, function, subsets));
     126            0 : }
     127              : 
     128              : template <typename TDomain, typename TAlgebra>
     129            0 : void DirichletBoundary<TDomain, TAlgebra>::
     130              : add(number value, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     131              : {
     132              :         std::string function;
     133            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     134            0 :                 if(i > 0) function.append(",");
     135              :                 function.append(Fcts[i]);
     136              :         }
     137              :         std::string subsets;
     138            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     139            0 :                 if(i > 0) subsets.append(",");
     140              :                 subsets.append(Subsets[i]);
     141              :         }
     142              : 
     143            0 :         add(value, function.c_str(), subsets.c_str());
     144            0 : }
     145              : 
     146              : template <typename TDomain, typename TAlgebra>
     147            0 : void DirichletBoundary<TDomain, TAlgebra>::
     148              : add(SmartPtr<UserData<MathVector<dim>, dim> > func, const char* functions, const char* subsets)
     149              : {
     150            0 :         m_vVectorData.push_back(VectorData(func, functions, subsets));
     151            0 : }
     152              : 
     153              : template <typename TDomain, typename TAlgebra>
     154            0 : void DirichletBoundary<TDomain, TAlgebra>::
     155              : add(SmartPtr<UserData<MathVector<dim>, dim> > func, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     156              : {
     157              :         std::string function;
     158            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     159            0 :                 if(i > 0) function.append(",");
     160              :                 function.append(Fcts[i]);
     161              :         }
     162              :         std::string subsets;
     163            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     164            0 :                 if(i > 0) subsets.append(",");
     165              :                 subsets.append(Subsets[i]);
     166              :         }
     167              : 
     168            0 :         add(func, function.c_str(), subsets.c_str());
     169            0 : }
     170              : 
     171              : #ifdef UG_FOR_LUA
     172              : template <typename TDomain, typename TAlgebra>
     173            0 : void DirichletBoundary<TDomain, TAlgebra>::
     174              : add(const char* name, const char* function, const char* subsets)
     175              : {
     176            0 :         if(LuaUserData<number, dim>::check_callback_returns(name)){
     177            0 :                 SmartPtr<UserData<number, dim> > sp =
     178              :                                                         LuaUserDataFactory<number, dim>::create(name);
     179            0 :                 add(sp, function, subsets);
     180              :                 return;
     181              :         }
     182            0 :         if(LuaUserData<number, dim, bool>::check_callback_returns(name)){
     183            0 :                 SmartPtr<UserData<number, dim, bool> > sp =
     184              :                                                 LuaUserDataFactory<number, dim, bool>::create(name);
     185            0 :                 add(sp, function, subsets);
     186              :                 return;
     187              :         }
     188            0 :         if(LuaUserData<MathVector<dim>, dim>::check_callback_returns(name)){
     189            0 :                 SmartPtr<UserData<MathVector<dim>, dim> > sp =
     190              :                                 LuaUserDataFactory<MathVector<dim>, dim>::create(name);
     191            0 :                 add(sp, function, subsets);
     192              :                 return;
     193              :         }
     194              : 
     195              : //      no match found
     196            0 :         if(!CheckLuaCallbackName(name))
     197            0 :                 UG_THROW("LagrangeDirichlet::add: Lua-Callback with name '"<<name<<
     198              :                                "' does not exist.");
     199              : 
     200              : //      name exists but wrong signature
     201            0 :         UG_THROW("LagrangeDirichlet::add: Cannot find matching callback "
     202              :                                         "signature. Use one of:\n"
     203              :                                         "a) Number - Callback\n"
     204              :                                         << (LuaUserData<number, dim>::signature()) << "\n" <<
     205              :                                         "b) Conditional Number - Callback\n"
     206              :                                         << (LuaUserData<number, dim, bool>::signature()) << "\n" <<
     207              :                                         "c) "<<dim<<"d Vector - Callback\n"
     208              :                                         << (LuaUserData<MathVector<dim>, dim>::signature()));
     209              : }
     210              : 
     211              : template <typename TDomain, typename TAlgebra>
     212            0 : void DirichletBoundary<TDomain, TAlgebra>::
     213              : add(const char* name, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     214              : {
     215              :         std::string function;
     216            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     217            0 :                 if(i > 0) function.append(",");
     218              :                 function.append(Fcts[i]);
     219              :         }
     220              :         std::string subsets;
     221            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     222            0 :                 if(i > 0) subsets.append(",");
     223              :                 subsets.append(Subsets[i]);
     224              :         }
     225              : 
     226            0 :         add(name, function.c_str(), subsets.c_str());
     227            0 : }
     228              : 
     229              : template <typename TDomain, typename TAlgebra>
     230            0 : void DirichletBoundary<TDomain, TAlgebra>::
     231              : add(LuaFunctionHandle fct, const char* function, const char* subsets)
     232              : {
     233            0 :         if(LuaUserData<number, dim>::check_callback_returns(fct)){
     234            0 :                 SmartPtr<UserData<number, dim> > sp =
     235            0 :                                 make_sp(new LuaUserData<number, dim>(fct));
     236            0 :                 add(sp, function, subsets);
     237              :                 return;
     238              :         }
     239            0 :         if(LuaUserData<number, dim, bool>::check_callback_returns(fct)){
     240            0 :                 SmartPtr<UserData<number, dim, bool> > sp =
     241            0 :                                 make_sp(new LuaUserData<number, dim, bool>(fct));
     242            0 :                 add(sp, function, subsets);
     243              :                 return;
     244              :         }
     245            0 :         if(LuaUserData<MathVector<dim>, dim>::check_callback_returns(fct)){
     246            0 :                 SmartPtr<UserData<MathVector<dim>, dim> > sp =
     247            0 :                                 make_sp(new LuaUserData<MathVector<dim>, dim>(fct));
     248            0 :                 add(sp, function, subsets);
     249              :                 return;
     250              :         }
     251              : 
     252              : //      name exists but wrong signature
     253            0 :         UG_THROW("LagrangeDirichlet::add: Cannot find matching callback "
     254              :                                         "signature. Use one of:\n"
     255              :                                         "a) Number - Callback\n"
     256              :                                         << (LuaUserData<number, dim>::signature()) << "\n" <<
     257              :                                         "b) Conditional Number - Callback\n"
     258              :                                         << (LuaUserData<number, dim, bool>::signature()) << "\n" <<
     259              :                                         "c) "<<dim<<"d Vector - Callback\n"
     260              :                                         << (LuaUserData<MathVector<dim>, dim>::signature()));
     261              : }
     262              : 
     263              : template <typename TDomain, typename TAlgebra>
     264            0 : void DirichletBoundary<TDomain, TAlgebra>::
     265              : add(LuaFunctionHandle fct, const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     266              : {
     267              :         std::string function;
     268            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     269            0 :                 if(i > 0) function.append(",");
     270              :                 function.append(Fcts[i]);
     271              :         }
     272              :         std::string subsets;
     273            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     274            0 :                 if(i > 0) subsets.append(",");
     275              :                 subsets.append(Subsets[i]);
     276              :         }
     277              : 
     278            0 :         add(fct, function.c_str(), subsets.c_str());
     279            0 : }
     280              : #endif
     281              : 
     282              : template <typename TDomain, typename TAlgebra>
     283            0 : void DirichletBoundary<TDomain, TAlgebra>::
     284              : add(const char* functions, const char* subsets)
     285              : {
     286            0 :         m_vOldNumberData.push_back(OldNumberData(functions, subsets));
     287            0 : }
     288              : 
     289              : template <typename TDomain, typename TAlgebra>
     290            0 : void DirichletBoundary<TDomain, TAlgebra>::
     291              : add(const std::vector<std::string>& Fcts, const std::vector<std::string>& Subsets)
     292              : {
     293              :         std::string function;
     294            0 :         for(size_t i = 0; i < Fcts.size(); ++i){
     295            0 :                 if(i > 0) function.append(",");
     296              :                 function.append(Fcts[i]);
     297              :         }
     298              :         std::string subsets;
     299            0 :         for(size_t i = 0; i < Subsets.size(); ++i){
     300            0 :                 if(i > 0) subsets.append(",");
     301              :                 subsets.append(Subsets[i]);
     302              :         }
     303              : 
     304            0 :         add(function.c_str(), subsets.c_str());
     305            0 : }
     306              : 
     307              : template <typename TDomain, typename TAlgebra>
     308            0 : void DirichletBoundary<TDomain, TAlgebra>::
     309              : check_functions_and_subsets(FunctionGroup& functionGroup, SubsetGroup& subsetGroup, size_t numFct) const
     310              : {
     311              : //      only number of functions allowed
     312            0 :         if(functionGroup.size() != numFct)
     313            0 :                 UG_THROW("DirichletBoundary:extract_data:"
     314              :                                         " Only "<<numFct<<" function(s) allowed in specification of a"
     315              :                                         " Dirichlet Value, but the following functions given:"
     316              :                                         <<functionGroup);
     317              : 
     318              : //      get subsethandler
     319            0 :         ConstSmartPtr<ISubsetHandler> pSH = m_spApproxSpace->subset_handler();
     320              : 
     321              : //      loop subsets
     322            0 :         for(size_t si = 0; si < subsetGroup.size(); ++si)
     323              :         {
     324              :         //      get subset index
     325              :                 const int subsetIndex = subsetGroup[si];
     326              : 
     327              :         //      check that subsetIndex is valid
     328            0 :                 if(subsetIndex < 0 || subsetIndex >= pSH->num_subsets())
     329            0 :                         UG_THROW("DirichletBoundary:extract_data:"
     330              :                                                         " Invalid Subset Index " << subsetIndex << ". (Valid is"
     331              :                                                         " 0, .. , " << pSH->num_subsets() <<").");
     332              : 
     333              :         //      check all functions
     334            0 :                 for(size_t i=0; i < functionGroup.size(); ++i)
     335              :                 {
     336              :                         const size_t fct = functionGroup[i];
     337              : 
     338              :                 //      check if function exist
     339            0 :                         if(fct >= m_spApproxSpace->num_fct())
     340            0 :                                 UG_THROW("DirichletBoundary:extract_data:"
     341              :                                                         " Function "<< fct << " does not exist in pattern.");
     342              : 
     343              :                 //      check that function is defined for segment
     344            0 :                         if(!m_spApproxSpace->is_def_in_subset(fct, subsetIndex))
     345            0 :                                 UG_THROW("DirichletBoundary:extract_data:"
     346              :                                                                 " Function "<<fct<<" not defined on subset "<<subsetIndex);
     347              :                 }
     348              :         }
     349              : 
     350              : //      everything ok
     351            0 : }
     352              : 
     353              : template <typename TDomain, typename TAlgebra>
     354              : template <typename TUserData, typename TScheduledUserData>
     355            0 : void DirichletBoundary<TDomain, TAlgebra>::
     356              : extract_data(std::map<int, std::vector<TUserData*> >& mvUserDataBndSegment,
     357              :              std::vector<TScheduledUserData>& vUserData)
     358              : {
     359              : //      clear the extracted data
     360              :         mvUserDataBndSegment.clear();
     361              : 
     362            0 :         for(size_t i = 0; i < vUserData.size(); ++i)
     363              :         {
     364              :         //      create Function Group and Subset Group
     365              :                 try
     366              :                 {
     367            0 :                         if (! m_bInvertSubsetSelection)
     368            0 :                                 vUserData[i].ssGrp = m_spApproxSpace->subset_grp_by_name
     369              :                                         (vUserData[i].ssName.c_str());
     370              :                         else
     371            0 :                                 vUserData[i].ssGrp = m_spApproxSpace->all_subsets_grp_except_for
     372              :                                         (vUserData[i].ssName.c_str());
     373              :                 }
     374            0 :                 UG_CATCH_THROW(" Subsets '"<<vUserData[i].ssName<<"' not"
     375              :                                 " all contained in ApproximationSpace.");
     376              : 
     377            0 :                 FunctionGroup fctGrp;
     378              :                 try{
     379            0 :                         fctGrp = m_spApproxSpace->fct_grp_by_name(vUserData[i].fctName.c_str());
     380            0 :                 }UG_CATCH_THROW(" Functions '"<<vUserData[i].fctName<<"' not"
     381              :                                 " all contained in ApproximationSpace.");
     382              : 
     383              :         //      check functions and subsets
     384            0 :                 check_functions_and_subsets(fctGrp, vUserData[i].ssGrp, TUserData::numFct);
     385              : 
     386              :         //      set functions
     387            0 :                 if(fctGrp.size() != TUserData::numFct)
     388            0 :                         UG_THROW("LagrangeDirichletBoundary: wrong number of fct");
     389              : 
     390            0 :                 for(size_t fct = 0; fct < TUserData::numFct; ++fct)
     391              :                 {
     392            0 :                         vUserData[i].fct[fct] = fctGrp[fct];
     393              :                 }
     394              : 
     395              :         //      loop subsets
     396            0 :                 for(size_t si = 0; si < vUserData[i].ssGrp.size(); ++si)
     397              :                 {
     398              :                 //      get subset index and function
     399            0 :                         const int subsetIndex = vUserData[i].ssGrp[si];
     400              : 
     401              :                 //      remember functor and function
     402            0 :                         mvUserDataBndSegment[subsetIndex].push_back(&vUserData[i]);
     403              :                 }
     404              :         }
     405            0 : }
     406              : 
     407              : 
     408              : template <typename TDomain, typename TAlgebra>
     409            0 : void DirichletBoundary<TDomain, TAlgebra>::
     410              : extract_data()
     411              : {
     412              : //      check that function pattern exists
     413            0 :         if(!m_spApproxSpace.valid())
     414            0 :                 UG_THROW("DirichletBoundary:extract_data: "
     415              :                                 " Approximation Space not set.");
     416              : 
     417            0 :         extract_data(m_mNumberBndSegment, m_vNumberData);
     418            0 :         extract_data(m_mBNDNumberBndSegment, m_vBNDNumberData);
     419            0 :         extract_data(m_mConstNumberBndSegment, m_vConstNumberData);
     420            0 :         extract_data(m_mVectorBndSegment, m_vVectorData);
     421            0 :         extract_data(m_mOldNumberBndSegment, m_vOldNumberData);
     422            0 : }
     423              : 
     424              : ////////////////////////////////////////////////////////////////////////////////
     425              : //      assemble_dirichlet_rows
     426              : ////////////////////////////////////////////////////////////////////////////////
     427              : 
     428              : template <typename TDomain, typename TAlgebra>
     429              : void DirichletBoundary<TDomain, TAlgebra>::
     430              : assemble_dirichlet_rows(matrix_type& mat, ConstSmartPtr<DoFDistribution> dd, number time)
     431              : {
     432              :         extract_data();
     433              : 
     434              : //      loop boundary subsets
     435              :         typename std::map<int, std::vector<CondNumberData*> >::const_iterator iter;
     436              :         for(iter = m_mBNDNumberBndSegment.begin(); iter != m_mBNDNumberBndSegment.end(); ++iter)
     437              :         {
     438              :                 int si = (*iter).first;
     439              :                 const std::vector<CondNumberData*>& userData = (*iter).second;
     440              : 
     441              :                 DoFDistribution::traits<Vertex>::const_iterator iterBegin         = dd->begin<Vertex>(si);
     442              :                 DoFDistribution::traits<Vertex>::const_iterator iterEnd   = dd->end<Vertex>(si);
     443              : 
     444              :         //      create Multiindex
     445              :                 std::vector<DoFIndex> multInd;
     446              : 
     447              :         //      for readin
     448              :                 MathVector<1> val;
     449              :                 position_type corner;
     450              : 
     451              :         //      loop vertices
     452              :                 for(DoFDistribution::traits<Vertex>::const_iterator iter = iterBegin; iter != iterEnd; iter++)
     453              :                 {
     454              :                 //      get vertex
     455              :                         Vertex* vertex = *iter;
     456              : 
     457              :                 //      get corner position
     458              :                         corner = m_aaPos[vertex];
     459              : 
     460              :                 //      loop dirichlet functions on this segment
     461              :                         for(size_t i = 0; i < userData.size(); ++i)
     462              :                         {
     463              :                         //      check if function is dirichlet
     464              :                                 if(!(*userData[i])(val, corner, time, si)) continue;
     465              : 
     466              :                         //      get function index
     467              :                                 const size_t fct = userData[i]->fct[0];
     468              : 
     469              :                         //      get multi indices
     470              :                                 if(dd->inner_dof_indices(vertex, fct, multInd) != 1)
     471              :                                         return;
     472              : 
     473              :                                 this->m_spAssTuner->set_dirichlet_row(mat, multInd[0]);
     474              :                         }
     475              :                 }
     476              :         }
     477              : }
     478              : 
     479              : ////////////////////////////////////////////////////////////////////////////////
     480              : //      adjust TRANSFER
     481              : ////////////////////////////////////////////////////////////////////////////////
     482              : 
     483              : 
     484              : template <typename TDomain, typename TAlgebra>
     485            0 : void DirichletBoundary<TDomain, TAlgebra>::
     486              : adjust_prolongation(matrix_type& P,
     487              :                     ConstSmartPtr<DoFDistribution> ddFine,
     488              :                     ConstSmartPtr<DoFDistribution> ddCoarse,
     489              :                                         int type,
     490              :                     number time)
     491              : {
     492              : #ifdef LAGRANGE_DIRICHLET_ADJ_TRANSFER_FIX
     493              :          if (!m_bAdjustTransfers)
     494              :          {
     495              :                  std::cerr << "Avoiding  adjust_prolongation" << std::endl;
     496              :                  return;
     497              :         }
     498              : #endif
     499            0 :         extract_data();
     500              : 
     501            0 :         adjust_prolongation<CondNumberData>(m_mBNDNumberBndSegment, P, ddFine, ddCoarse, time);
     502            0 :         adjust_prolongation<NumberData>(m_mNumberBndSegment, P, ddFine, ddCoarse, time);
     503            0 :         adjust_prolongation<ConstNumberData>(m_mConstNumberBndSegment, P, ddFine, ddCoarse, time);
     504              : 
     505            0 :         adjust_prolongation<VectorData>(m_mVectorBndSegment, P, ddFine, ddCoarse, time);
     506              : 
     507            0 :         adjust_prolongation<OldNumberData>(m_mOldNumberBndSegment, P, ddFine, ddCoarse, time);
     508            0 : }
     509              : 
     510              : template <typename TDomain, typename TAlgebra>
     511              : template <typename TUserData>
     512            0 : void DirichletBoundary<TDomain, TAlgebra>::
     513              : adjust_prolongation(const std::map<int, std::vector<TUserData*> >& mvUserData,
     514              :                     matrix_type& P,
     515              :                     ConstSmartPtr<DoFDistribution> ddFine,
     516              :                     ConstSmartPtr<DoFDistribution> ddCoarse,
     517              :                     number time)
     518              : {
     519              : //      loop boundary subsets
     520              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
     521            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
     522              :         {
     523              :         //      get subset index
     524            0 :                 const int si = (*iter).first;
     525              : 
     526              :         //      get vector of scheduled dirichlet data on this subset
     527            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
     528              : 
     529              :         //      adapt jacobian for dofs in each base element type
     530              :                 try
     531              :                 {
     532            0 :                 if(ddFine->max_dofs(VERTEX)) adjust_prolongation<RegularVertex, TUserData>(vUserData, si, P, ddFine, ddCoarse, time);
     533            0 :                 if(ddFine->max_dofs(EDGE))   adjust_prolongation<Edge, TUserData>(vUserData, si, P, ddFine, ddCoarse, time);
     534            0 :                 if(ddFine->max_dofs(FACE))   adjust_prolongation<Face, TUserData>(vUserData, si, P, ddFine, ddCoarse, time);
     535            0 :                 if(ddFine->max_dofs(VOLUME)) adjust_prolongation<Volume, TUserData>(vUserData, si, P, ddFine, ddCoarse, time);
     536              :                 }
     537            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_prolongation:"
     538              :                                                 " While calling 'adapt_prolongation' for TUserData, aborting.");
     539              :         }
     540            0 : }
     541              : 
     542              : template <typename TDomain, typename TAlgebra>
     543              : template <typename TBaseElem, typename TUserData>
     544            0 : void DirichletBoundary<TDomain, TAlgebra>::
     545              : adjust_prolongation(const std::vector<TUserData*>& vUserData, int si,
     546              :                     matrix_type& P,
     547              :                     ConstSmartPtr<DoFDistribution> ddFine,
     548              :                     ConstSmartPtr<DoFDistribution> ddCoarse,
     549              :                     number time)
     550              : {
     551              : //      create Multiindex
     552              :         std::vector<DoFIndex> vFineDoF, vCoarseDoF;
     553              : 
     554              : //      dummy for readin
     555              :         typename TUserData::value_type val;
     556              : 
     557              : //      position of dofs
     558              :         std::vector<position_type> vPos;
     559              : 
     560              : //      iterators
     561              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     562            0 :         iter = ddFine->begin<TBaseElem>(si);
     563            0 :         iterEnd = ddFine->end<TBaseElem>(si);
     564              : 
     565              : //      loop elements
     566            0 :         for( ; iter != iterEnd; iter++)
     567              :         {
     568              :         //      get vertex
     569              :                 TBaseElem* elem = *iter;
     570            0 :                 GridObject* parent = m_spDomain->grid()->get_parent(elem);
     571            0 :                 if(!parent) continue;
     572            0 :                 if(!ddCoarse->is_contained(parent)) continue;
     573              : 
     574              :         //      loop dirichlet functions on this segment
     575            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
     576              :                 {
     577            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
     578              :                         {
     579              :                         //      get function index
     580            0 :                                 const size_t fct = vUserData[i]->fct[f];
     581              : 
     582              :                         //      get local finite element id
     583              :                                 const LFEID& lfeID = ddFine->local_finite_element_id(fct);
     584              : 
     585              :                         //      get multi indices
     586            0 :                                 ddFine->inner_dof_indices(elem, fct, vFineDoF);
     587            0 :                                 ddCoarse->inner_dof_indices(parent, fct, vCoarseDoF);
     588              : 
     589              :                         //      get dof position
     590              :                                 if(TUserData::isConditional){
     591            0 :                                         InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
     592              :                                         UG_ASSERT(vFineDoF.size() == vPos.size(), "Size mismatch");
     593              :                                 }
     594              : 
     595              :                         //      loop dofs on element
     596            0 :                                 for(size_t j = 0; j < vFineDoF.size(); ++j)
     597              :                                 {
     598              :                                 //      check if function is dirichlet
     599              :                                         if(TUserData::isConditional){
     600            0 :                                                 if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
     601              :                                         }
     602              : 
     603              :                                         SetRow(P, vFineDoF[j], 0.0);
     604              :                                 }
     605              : 
     606            0 :                                 if(vFineDoF.size() > 0){
     607            0 :                                         for(size_t k = 0; k < vCoarseDoF.size(); ++k){
     608            0 :                                                 DoFRef(P, vFineDoF[0], vCoarseDoF[k]) = 1.0;
     609              :                                         }
     610              :                                 }
     611              :                         }
     612              :                 }
     613              :         }
     614            0 : }
     615              : 
     616              : template <typename TDomain, typename TAlgebra>
     617            0 : void DirichletBoundary<TDomain, TAlgebra>::
     618              : adjust_restriction(matrix_type& R,
     619              :                                         ConstSmartPtr<DoFDistribution> ddCoarse,
     620              :                                         ConstSmartPtr<DoFDistribution> ddFine,
     621              :                                         int type,
     622              :                                         number time)
     623              : {
     624              : #ifdef LAGRANGE_DIRICHLET_ADJ_TRANSFER_FIX
     625              :         if (!m_bAdjustTransfers)
     626              :         {
     627              :                 std::cerr << "Avoiding adjust_restriction" << std::endl;
     628              :                 return;
     629              :         }
     630              : #endif
     631            0 :         extract_data();
     632              : 
     633            0 :         adjust_restriction<CondNumberData>(m_mBNDNumberBndSegment, R, ddCoarse, ddFine, time);
     634            0 :         adjust_restriction<NumberData>(m_mNumberBndSegment, R, ddCoarse, ddFine, time);
     635            0 :         adjust_restriction<ConstNumberData>(m_mConstNumberBndSegment, R, ddCoarse, ddFine, time);
     636              : 
     637            0 :         adjust_restriction<VectorData>(m_mVectorBndSegment, R, ddCoarse, ddFine, time);
     638              : 
     639            0 :         adjust_restriction<OldNumberData>(m_mOldNumberBndSegment, R, ddCoarse, ddFine, time);
     640            0 : }
     641              : 
     642              : template <typename TDomain, typename TAlgebra>
     643              : template <typename TUserData>
     644            0 : void DirichletBoundary<TDomain, TAlgebra>::
     645              : adjust_restriction(const std::map<int, std::vector<TUserData*> >& mvUserData,
     646              :                    matrix_type& R,
     647              :                    ConstSmartPtr<DoFDistribution> ddCoarse,
     648              :                    ConstSmartPtr<DoFDistribution> ddFine,
     649              :                    number time)
     650              : {
     651              : //      loop boundary subsets
     652              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
     653            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
     654              :         {
     655              :         //      get subset index
     656            0 :                 const int si = (*iter).first;
     657              : 
     658              :         //      get vector of scheduled dirichlet data on this subset
     659            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
     660              : 
     661              :         //      adapt jacobian for dofs in each base element type
     662              :                 try
     663              :                 {
     664            0 :                 if(ddFine->max_dofs(VERTEX)) adjust_restriction<RegularVertex, TUserData>(vUserData, si, R, ddCoarse, ddFine, time);
     665            0 :                 if(ddFine->max_dofs(EDGE))   adjust_restriction<Edge, TUserData>(vUserData, si, R, ddCoarse, ddFine, time);
     666            0 :                 if(ddFine->max_dofs(FACE))   adjust_restriction<Face, TUserData>(vUserData, si, R, ddCoarse, ddFine, time);
     667            0 :                 if(ddFine->max_dofs(VOLUME)) adjust_restriction<Volume, TUserData>(vUserData, si, R, ddCoarse, ddFine, time);
     668              :                 }
     669            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_restriction:"
     670              :                                                 " While calling 'adjust_restriction' for TUserData, aborting.");
     671              :         }
     672            0 : }
     673              : 
     674              : template <typename TDomain, typename TAlgebra>
     675              : template <typename TBaseElem, typename TUserData>
     676            0 : void DirichletBoundary<TDomain, TAlgebra>::
     677              : adjust_restriction(const std::vector<TUserData*>& vUserData, int si,
     678              :                    matrix_type& R,
     679              :                    ConstSmartPtr<DoFDistribution> ddCoarse,
     680              :                    ConstSmartPtr<DoFDistribution> ddFine,
     681              :                    number time)
     682              : {
     683              : //      create Multiindex
     684              :         std::vector<DoFIndex> vFineDoF, vCoarseDoF;
     685              : 
     686              : //      dummy for readin
     687              :         typename TUserData::value_type val;
     688              : 
     689              : //      position of dofs
     690              :         std::vector<position_type> vPos;
     691              : 
     692              : //      iterators
     693              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     694            0 :         iter = ddFine->begin<TBaseElem>(si);
     695            0 :         iterEnd = ddFine->end<TBaseElem>(si);
     696              : 
     697              : //      loop elements
     698            0 :         for( ; iter != iterEnd; iter++)
     699              :         {
     700              :         //      get vertex
     701              :                 TBaseElem* elem = *iter;
     702            0 :                 GridObject* parent = m_spDomain->grid()->get_parent(elem);
     703            0 :                 if(!parent) continue;
     704            0 :                 if(!ddCoarse->is_contained(parent)) continue;
     705              : 
     706              :         //      loop dirichlet functions on this segment
     707            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
     708              :                 {
     709            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
     710              :                         {
     711              :                         //      get function index
     712            0 :                                 const size_t fct = vUserData[i]->fct[f];
     713              : 
     714              :                         //      get local finite element id
     715              :                                 const LFEID& lfeID = ddFine->local_finite_element_id(fct);
     716              : 
     717              :                         //      get multi indices
     718            0 :                                 ddFine->inner_dof_indices(elem, fct, vFineDoF);
     719            0 :                                 ddCoarse->inner_dof_indices(parent, fct, vCoarseDoF);
     720              : 
     721              :                         //      get dof position
     722              :                                 if(TUserData::isConditional){
     723            0 :                                         InnerDoFPosition<TDomain>(vPos, parent, *m_spDomain, lfeID);
     724              :                                         UG_ASSERT(vCoarseDoF.size() == vPos.size(), "Size mismatch");
     725              :                                 }
     726              : 
     727              :                         //      loop dofs on element
     728            0 :                                 for(size_t j = 0; j < vCoarseDoF.size(); ++j)
     729              :                                 {
     730              :                                 //      check if function is dirichlet
     731              :                                         if(TUserData::isConditional){
     732            0 :                                                 if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
     733              :                                         }
     734              : 
     735              :                                         SetRow(R, vCoarseDoF[j], 0.0);
     736              :                                 }
     737              : 
     738            0 :                                 if(vFineDoF.size() > 0){
     739            0 :                                         for(size_t k = 0; k < vCoarseDoF.size(); ++k){
     740            0 :                                                 DoFRef(R, vCoarseDoF[k], vFineDoF[0]) = 1.0;
     741              :                                         }
     742              :                                 }
     743              :                         }
     744              :                 }
     745              :         }
     746            0 : }
     747              : 
     748              : ////////////////////////////////////////////////////////////////////////////////
     749              : //      adjust JACOBIAN
     750              : ////////////////////////////////////////////////////////////////////////////////
     751              : 
     752              : template <typename TDomain, typename TAlgebra>
     753            0 : void DirichletBoundary<TDomain, TAlgebra>::
     754              : adjust_jacobian(matrix_type& J, const vector_type& u,
     755              :                 ConstSmartPtr<DoFDistribution> dd, int type, number time,
     756              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     757              :                 const number s_a0)
     758              : {
     759            0 :         extract_data();
     760              : 
     761            0 :         adjust_jacobian<CondNumberData>(m_mBNDNumberBndSegment, J, u, dd, time);
     762            0 :         adjust_jacobian<NumberData>(m_mNumberBndSegment, J, u, dd, time);
     763            0 :         adjust_jacobian<ConstNumberData>(m_mConstNumberBndSegment, J, u, dd, time);
     764              : 
     765            0 :         adjust_jacobian<VectorData>(m_mVectorBndSegment, J, u, dd, time);
     766              : 
     767            0 :         adjust_jacobian<OldNumberData>(m_mOldNumberBndSegment, J, u, dd, time);
     768            0 : }
     769              : 
     770              : 
     771              : template <typename TDomain, typename TAlgebra>
     772              : template <typename TUserData>
     773            0 : void DirichletBoundary<TDomain, TAlgebra>::
     774              : adjust_jacobian(const std::map<int, std::vector<TUserData*> >& mvUserData,
     775              :                 matrix_type& J, const vector_type& u,
     776              :                     ConstSmartPtr<DoFDistribution> dd, number time)
     777              : {
     778              : //      loop boundary subsets
     779              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
     780            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
     781              :         {
     782              :         //      get subset index
     783            0 :                 const int si = (*iter).first;
     784              : 
     785              :         //      get vector of scheduled dirichlet data on this subset
     786            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
     787              : 
     788              :         //      adapt jacobian for dofs in each base element type
     789              :                 try
     790              :                 {
     791            0 :                 if(dd->max_dofs(VERTEX))
     792            0 :                         adjust_jacobian<RegularVertex, TUserData>(vUserData, si, J, u, dd, time);
     793            0 :                 if(dd->max_dofs(EDGE))
     794            0 :                         adjust_jacobian<Edge, TUserData>(vUserData, si, J, u, dd, time);
     795            0 :                 if(dd->max_dofs(FACE))
     796            0 :                         adjust_jacobian<Face, TUserData>(vUserData, si, J, u, dd, time);
     797            0 :                 if(dd->max_dofs(VOLUME))
     798            0 :                         adjust_jacobian<Volume, TUserData>(vUserData, si, J, u, dd, time);
     799              :                 }
     800            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_jacobian:"
     801              :                                                 " While calling 'adapt_jacobian' for TUserData, aborting.");
     802              :         }
     803            0 : }
     804              : 
     805              : template <typename TDomain, typename TAlgebra>
     806              : template <typename TBaseElem, typename TUserData>
     807            0 : void DirichletBoundary<TDomain, TAlgebra>::
     808              : adjust_jacobian(const std::vector<TUserData*>& vUserData, int si,
     809              :                 matrix_type& J, const vector_type& u,
     810              :                     ConstSmartPtr<DoFDistribution> dd, number time)
     811              : {
     812              : //      create Multiindex
     813              :         std::vector<DoFIndex> multInd;
     814              : 
     815              : //      dummy for readin
     816              :         typename TUserData::value_type val;
     817              : 
     818              : //      position of dofs
     819              :         std::vector<position_type> vPos;
     820              : 
     821              : //      save all dirichlet degree of freedom indices.
     822              :         std::set<size_t> dirichletDoFIndices;
     823              : 
     824              : 
     825              : //      iterators
     826              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     827            0 :         iter = dd->begin<TBaseElem>(si);
     828            0 :         iterEnd = dd->end<TBaseElem>(si);
     829              : 
     830              : //      loop elements
     831            0 :         for( ; iter != iterEnd; iter++)
     832              :         {
     833              :         //      get vertex
     834              :                 TBaseElem* elem = *iter;
     835              : 
     836              :         //      loop dirichlet functions on this segment
     837            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
     838              :                 {
     839            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
     840              :                         {
     841              :                         //      get function index
     842            0 :                                 const size_t fct = vUserData[i]->fct[f];
     843              : 
     844              :                         //      get local finite element id
     845              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
     846              : 
     847              :                         //      get multi indices
     848            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
     849              : 
     850              :                         //      get dof position
     851              :                                 if(TUserData::isConditional){
     852            0 :                                         InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
     853              :                                         UG_ASSERT(multInd.size() == vPos.size(), "Size mismatch");
     854              :                                 }
     855              : 
     856              :                         //      loop dofs on element
     857            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
     858              :                                 {
     859              :                                 //      check if function is dirichlet
     860              :                                         if(TUserData::isConditional){
     861            0 :                                                 if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
     862              :                                         }
     863              : 
     864            0 :                                         this->m_spAssTuner->set_dirichlet_row(J, multInd[j]);
     865            0 :                                         if(m_bDirichletColumns)
     866              :                                                 dirichletDoFIndices.insert(multInd[j][0]);
     867              :                                 }
     868              :                         }
     869              :                 }
     870              :         }
     871              : 
     872              : 
     873            0 :         if(m_bDirichletColumns){
     874              :         //      UG_LOG("adjust jacobian\n")
     875              : 
     876              :                 // number of rows
     877              :                 size_t nr = J.num_rows();
     878              : 
     879              :                 // run over all rows of the local matrix J and save the colums
     880              :                 // entries for the Dirichlet indices in the map
     881              : 
     882              :                 typename std::set<size_t>::iterator currentDIndex;
     883              : 
     884            0 :                 for(size_t i = 0; i<nr; i++)
     885              :                 {
     886            0 :                         for(typename matrix_type::row_iterator it = J.begin_row(i); it!=J.end_row(i); ++it){
     887              : 
     888              :                                 // look if the current index is a dirichlet index
     889              :                                 // if it.index is a dirichlet index
     890              :                                 // the iterator currentDIndex is delivered otherwise set::end()
     891              :                                 currentDIndex = dirichletDoFIndices.find(it.index());
     892              : 
     893              :                                 // fill dirichletMap & set corresponding entry to zero
     894            0 :                                 if(currentDIndex != dirichletDoFIndices.end()){
     895              :                                         // the dirichlet-dof-index it.index is assigned
     896              :                                         // the row i and the matrix entry it.value().
     897              :                                         // if necessary for defect remove comment
     898              : 
     899              :                                                 //      m_dirichletMap[it.index()][i] = it.value();
     900              : 
     901              :                                         // the corresponding entry at column it.index() is set zero
     902              :                                         // this corresponds to a dirichlet column.
     903              :                                         // diagonal stays unchanged
     904            0 :                                         if(i!=it.index())
     905            0 :                                                 it.value() = 0.0;
     906              :                                 }
     907              : 
     908              :                         }
     909              :                 }
     910              :         }
     911              : 
     912            0 : }
     913              : 
     914              : ////////////////////////////////////////////////////////////////////////////////
     915              : //      adjust DEFECT
     916              : ////////////////////////////////////////////////////////////////////////////////
     917              : 
     918              : template <typename TDomain, typename TAlgebra>
     919            0 : void DirichletBoundary<TDomain, TAlgebra>::
     920              : adjust_defect(vector_type& d, const vector_type& u,
     921              :               ConstSmartPtr<DoFDistribution> dd, int type, number time,
     922              :               ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     923              :                           const std::vector<number>* vScaleMass,
     924              :                           const std::vector<number>* vScaleStiff)
     925              : {
     926            0 :         extract_data();
     927              : 
     928            0 :         adjust_defect<CondNumberData>(m_mBNDNumberBndSegment, d, u, dd, time);
     929            0 :         adjust_defect<NumberData>(m_mNumberBndSegment, d, u, dd, time);
     930            0 :         adjust_defect<ConstNumberData>(m_mConstNumberBndSegment, d, u, dd, time);
     931              : 
     932            0 :         adjust_defect<VectorData>(m_mVectorBndSegment, d, u, dd, time);
     933              : 
     934            0 :         adjust_defect<OldNumberData>(m_mOldNumberBndSegment, d, u, dd, time);
     935            0 : }
     936              : 
     937              : 
     938              : template <typename TDomain, typename TAlgebra>
     939              : template <typename TUserData>
     940            0 : void DirichletBoundary<TDomain, TAlgebra>::
     941              : adjust_defect(const std::map<int, std::vector<TUserData*> >& mvUserData,
     942              :                vector_type& d, const vector_type& u,
     943              :                ConstSmartPtr<DoFDistribution> dd, number time)
     944              : {
     945              : //      loop boundary subsets
     946              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
     947            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
     948              :         {
     949              :         //      get subset index
     950            0 :                 const int si = (*iter).first;
     951              : 
     952              :         //      get vector of scheduled dirichlet data on this subset
     953            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
     954              : 
     955              :         //      adapt jacobian for dofs in each base element type
     956              :                 try
     957              :                 {
     958            0 :                 if(dd->max_dofs(VERTEX))
     959            0 :                         adjust_defect<RegularVertex, TUserData>(vUserData, si, d, u, dd, time);
     960            0 :                 if(dd->max_dofs(EDGE))
     961            0 :                         adjust_defect<Edge, TUserData>(vUserData, si, d, u, dd, time);
     962            0 :                 if(dd->max_dofs(FACE))
     963            0 :                         adjust_defect<Face, TUserData>(vUserData, si, d, u, dd, time);
     964            0 :                 if(dd->max_dofs(VOLUME))
     965            0 :                         adjust_defect<Volume, TUserData>(vUserData, si, d, u, dd, time);
     966              :                 }
     967            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_defect:"
     968              :                                                 " While calling 'adjust_defect' for TUserData, aborting.");
     969              :         }
     970            0 : }
     971              : 
     972              : template <typename TDomain, typename TAlgebra>
     973              : template <typename TBaseElem, typename TUserData>
     974            0 : void DirichletBoundary<TDomain, TAlgebra>::
     975              : adjust_defect(const std::vector<TUserData*>& vUserData, int si,
     976              :               vector_type& d, const vector_type& u,
     977              :               ConstSmartPtr<DoFDistribution> dd, number time)
     978              : {
     979              : //      create Multiindex
     980              :         std::vector<DoFIndex> multInd;
     981              : 
     982              : //      dummy for readin
     983              :         typename TUserData::value_type val;
     984              : 
     985              : //      position of dofs
     986              :         std::vector<position_type> vPos;
     987              : 
     988              : //      iterators
     989              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
     990            0 :         iter = dd->begin<TBaseElem>(si);
     991            0 :         iterEnd = dd->end<TBaseElem>(si);
     992              : 
     993              : //      loop elements
     994            0 :         for( ; iter != iterEnd; iter++)
     995              :         {
     996              :         //      get vertex
     997              :                 TBaseElem* elem = *iter;
     998              : 
     999              :         //      loop dirichlet functions on this segment
    1000            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
    1001              :                 {
    1002            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1003              :                         {
    1004              :                         //      get function index
    1005            0 :                                 const size_t fct = vUserData[i]->fct[f];
    1006              : 
    1007              :                         //      get local finite element id
    1008              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
    1009              : 
    1010              :                         //      get multi indices
    1011            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
    1012              : 
    1013              :                         //      get dof position
    1014              :                                 if(TUserData::isConditional){
    1015            0 :                                         InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
    1016              :                                         UG_ASSERT(multInd.size() == vPos.size(), "Size mismatch. (multInd.size()="<<
    1017              :                                                   multInd.size()<<", vPos.size()="<<vPos.size()<<")");
    1018              :                                 }
    1019              : 
    1020              :                         //      loop dofs on element
    1021            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
    1022              :                                 {
    1023              :                                 //      check if function is dirichlet
    1024              :                                         if(TUserData::isConditional){
    1025            0 :                                                 if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
    1026              :                                         }
    1027              : 
    1028              :                                         //      set zero for dirichlet values
    1029            0 :                                         this->m_spAssTuner->set_dirichlet_val(d, multInd[j], 0.0);
    1030              :                                 }
    1031              :                         }
    1032              :                 }
    1033              :         }
    1034            0 : }
    1035              : 
    1036              : ////////////////////////////////////////////////////////////////////////////////
    1037              : //      adjust SOLUTION
    1038              : ////////////////////////////////////////////////////////////////////////////////
    1039              : 
    1040              : template <typename TDomain, typename TAlgebra>
    1041            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1042              : adjust_solution(vector_type& u, ConstSmartPtr<DoFDistribution> dd, int type, number time)
    1043              : {
    1044            0 :         extract_data();
    1045              : 
    1046            0 :         adjust_solution<CondNumberData>(m_mBNDNumberBndSegment, u, dd, time);
    1047            0 :         adjust_solution<NumberData>(m_mNumberBndSegment, u, dd, time);
    1048            0 :         adjust_solution<ConstNumberData>(m_mConstNumberBndSegment, u, dd, time);
    1049              : 
    1050            0 :         adjust_solution<VectorData>(m_mVectorBndSegment, u, dd, time);
    1051              : 
    1052            0 :         adjust_solution<OldNumberData>(m_mOldNumberBndSegment, u, dd, time);
    1053            0 : }
    1054              : 
    1055              : 
    1056              : template <typename TDomain, typename TAlgebra>
    1057              : template <typename TUserData>
    1058            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1059              : adjust_solution(const std::map<int, std::vector<TUserData*> >& mvUserData,
    1060              :                 vector_type& u, ConstSmartPtr<DoFDistribution> dd, number time)
    1061              : {
    1062              : //      loop boundary subsets
    1063              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
    1064            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
    1065              :         {
    1066              :         //      get subset index
    1067            0 :                 const int si = (*iter).first;
    1068              : 
    1069              :         //      get vector of scheduled dirichlet data on this subset
    1070            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
    1071              : 
    1072              :         //      adapt jacobian for dofs in each base element type
    1073              :                 try
    1074              :                 {
    1075            0 :                 if(dd->max_dofs(VERTEX))
    1076            0 :                         adjust_solution<RegularVertex, TUserData>(vUserData, si, u, dd, time);
    1077            0 :                 if(dd->max_dofs(EDGE))
    1078            0 :                         adjust_solution<Edge, TUserData>(vUserData, si, u, dd, time);
    1079            0 :                 if(dd->max_dofs(FACE))
    1080            0 :                         adjust_solution<Face, TUserData>(vUserData, si, u, dd, time);
    1081            0 :                 if(dd->max_dofs(VOLUME))
    1082            0 :                         adjust_solution<Volume, TUserData>(vUserData, si, u, dd, time);
    1083              :                 }
    1084            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_solution:"
    1085              :                                                 " While calling 'adjust_solution' for TUserData, aborting.");
    1086              :         }
    1087            0 : }
    1088              : 
    1089              : template <typename TDomain, typename TAlgebra>
    1090              : template <typename TBaseElem, typename TUserData>
    1091            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1092              : adjust_solution(const std::vector<TUserData*>& vUserData, int si,
    1093              :                 vector_type& u, ConstSmartPtr<DoFDistribution> dd, number time)
    1094              : {
    1095              : //      check if the solution is to be adjusted
    1096              :         if (! TUserData::setSolValue)
    1097              :                 return;
    1098              :         
    1099              : //      create Multiindex
    1100              :         std::vector<DoFIndex> multInd;
    1101              : 
    1102              : //      value readin
    1103              :         typename TUserData::value_type val;
    1104              : 
    1105              : //      position of dofs
    1106              :         std::vector<position_type> vPos;
    1107              : 
    1108              : //      iterators
    1109              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
    1110            0 :         iter = dd->begin<TBaseElem>(si);
    1111            0 :         iterEnd = dd->end<TBaseElem>(si);
    1112              : 
    1113              : //      loop elements
    1114            0 :         for( ; iter != iterEnd; iter++)
    1115              :         {
    1116              :         //      get vertex
    1117              :                 TBaseElem* elem = *iter;
    1118              : 
    1119              :         //      loop dirichlet functions on this segment
    1120            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
    1121              :                 {
    1122            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1123              :                         {
    1124              :                         //      get function index
    1125            0 :                                 const size_t fct = vUserData[i]->fct[f];
    1126              : 
    1127              :                         //      get local finite element id
    1128              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
    1129              : 
    1130              :                         //      get dof position
    1131            0 :                                 InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
    1132              : 
    1133              :                         //      get multi indices
    1134            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
    1135              : 
    1136              :                                 UG_ASSERT(multInd.size() == vPos.size(), "Size mismatch");
    1137              : 
    1138              :                         //      loop dofs on element
    1139            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
    1140              :                                 {
    1141              :                                 //  get dirichlet value
    1142            0 :                                         if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
    1143              : 
    1144            0 :                                         this->m_spAssTuner->set_dirichlet_val(u, multInd[j], val[f]);
    1145              :                                 }
    1146              :                         }
    1147              :                 }
    1148              :         }
    1149            0 : }
    1150              : 
    1151              : 
    1152              : 
    1153              : ////////////////////////////////////////////////////////////////////////////////
    1154              : //      adjust CORRECTION
    1155              : ////////////////////////////////////////////////////////////////////////////////
    1156              : 
    1157              : template <typename TDomain, typename TAlgebra>
    1158            0 : void DirichletBoundary<TDomain, TAlgebra>::adjust_correction
    1159              : (
    1160              :         vector_type& c,
    1161              :         ConstSmartPtr<DoFDistribution> dd,
    1162              :         int type,
    1163              :         number time
    1164              : )
    1165              : {
    1166            0 :         extract_data();
    1167              : 
    1168            0 :         adjust_correction<CondNumberData>(m_mBNDNumberBndSegment, c, dd, time);
    1169            0 :         adjust_correction<NumberData>(m_mNumberBndSegment, c, dd, time);
    1170            0 :         adjust_correction<ConstNumberData>(m_mConstNumberBndSegment, c, dd, time);
    1171              : 
    1172            0 :         adjust_correction<VectorData>(m_mVectorBndSegment, c, dd, time);
    1173              : 
    1174            0 :         adjust_correction<OldNumberData>(m_mOldNumberBndSegment, c, dd, time);
    1175            0 : }
    1176              : 
    1177              : template <typename TDomain, typename TAlgebra>
    1178              : template <typename TUserData>
    1179            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1180              : adjust_correction(const std::map<int, std::vector<TUserData*> >& mvUserData,
    1181              :                 vector_type& c, ConstSmartPtr<DoFDistribution> dd, number time)
    1182              : {
    1183              : //      loop boundary subsets
    1184              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
    1185            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
    1186              :         {
    1187              :         //      get subset index
    1188            0 :                 const int si = (*iter).first;
    1189              : 
    1190              :         //      get vector of scheduled dirichlet data on this subset
    1191            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
    1192              : 
    1193              :         //      adapt correction for dofs in each base element type
    1194              :                 try
    1195              :                 {
    1196            0 :                 if(dd->max_dofs(VERTEX))
    1197            0 :                         adjust_correction<RegularVertex, TUserData>(vUserData, si, c, dd, time);
    1198            0 :                 if(dd->max_dofs(EDGE))
    1199            0 :                         adjust_correction<Edge, TUserData>(vUserData, si,c, dd, time);
    1200            0 :                 if(dd->max_dofs(FACE))
    1201            0 :                         adjust_correction<Face, TUserData>(vUserData, si, c, dd, time);
    1202            0 :                 if(dd->max_dofs(VOLUME))
    1203            0 :                         adjust_correction<Volume, TUserData>(vUserData, si, c, dd, time);
    1204              :                 }
    1205            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_correction:"
    1206              :                                                 " While calling 'adjust_correction' for TUserData, aborting.");
    1207              :         }
    1208            0 : }
    1209              : 
    1210              : template <typename TDomain, typename TAlgebra>
    1211              : template <typename TBaseElem, typename TUserData>
    1212            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1213              : adjust_correction(const std::vector<TUserData*>& vUserData, int si,
    1214              :                 vector_type& c, ConstSmartPtr<DoFDistribution> dd, number time)
    1215              : {
    1216              : //      create Multiindex
    1217              :         std::vector<DoFIndex> multInd;
    1218              : 
    1219              : //      value readin
    1220              :         typename TUserData::value_type val;
    1221              : 
    1222              : //      position of dofs
    1223              :         std::vector<position_type> vPos;
    1224              : 
    1225              : //      iterators
    1226              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
    1227            0 :         iter = dd->begin<TBaseElem>(si);
    1228            0 :         iterEnd = dd->end<TBaseElem>(si);
    1229              : 
    1230              : //      loop elements
    1231            0 :         for( ; iter != iterEnd; iter++)
    1232              :         {
    1233              :         //      get vertex
    1234              :                 TBaseElem* elem = *iter;
    1235              : 
    1236              :         //      loop dirichlet functions on this segment
    1237            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
    1238              :                 {
    1239            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1240              :                         {
    1241              :                         //      get function index
    1242            0 :                                 const size_t fct = vUserData[i]->fct[f];
    1243              : 
    1244              :                         //      get local finite element id
    1245              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
    1246              : 
    1247              :                         //      get dof position
    1248            0 :                                 InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
    1249              : 
    1250              :                         //      get multi indices
    1251            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
    1252              : 
    1253              :                                 UG_ASSERT(multInd.size() == vPos.size(), "Size mismatch");
    1254              : 
    1255              :                         //      loop dofs on element
    1256            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
    1257              :                                 {
    1258              :                                 //  find out whether to use dirichlet value; concrete value is of no consequence
    1259            0 :                                         if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
    1260              : 
    1261            0 :                                         this->m_spAssTuner->set_dirichlet_val(c, multInd[j], 0.0);
    1262              :                                 }
    1263              :                         }
    1264              :                 }
    1265              :         }
    1266            0 : }
    1267              : 
    1268              : 
    1269              : ////////////////////////////////////////////////////////////////////////////////
    1270              : //      adjust LINEAR
    1271              : ////////////////////////////////////////////////////////////////////////////////
    1272              : 
    1273              : template <typename TDomain, typename TAlgebra>
    1274            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1275              : adjust_linear(matrix_type& A, vector_type& b,
    1276              :               ConstSmartPtr<DoFDistribution> dd, int type, number time)
    1277              : {
    1278            0 :         extract_data();
    1279              : 
    1280            0 :         adjust_linear<CondNumberData>(m_mBNDNumberBndSegment, A, b, dd, time);
    1281            0 :         adjust_linear<NumberData>(m_mNumberBndSegment, A, b, dd, time);
    1282            0 :         adjust_linear<ConstNumberData>(m_mConstNumberBndSegment, A, b, dd, time);
    1283              : 
    1284            0 :         adjust_linear<VectorData>(m_mVectorBndSegment, A, b, dd, time);
    1285              : 
    1286            0 :         adjust_linear<OldNumberData>(m_mOldNumberBndSegment, A, b, dd, time);
    1287            0 : }
    1288              : 
    1289              : 
    1290              : template <typename TDomain, typename TAlgebra>
    1291              : template <typename TUserData>
    1292            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1293              : adjust_linear(const std::map<int, std::vector<TUserData*> >& mvUserData,
    1294              :               matrix_type& A, vector_type& b,
    1295              :                   ConstSmartPtr<DoFDistribution> dd, number time)
    1296              : {
    1297              : //      loop boundary subsets
    1298              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
    1299            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
    1300              :         {
    1301              :         //      get subset index
    1302            0 :                 const int si = (*iter).first;
    1303              : 
    1304              :         //      get vector of scheduled dirichlet data on this subset
    1305            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
    1306              : 
    1307              :         //      adapt jacobian for dofs in each base element type
    1308              :                 try
    1309              :                 {
    1310            0 :                 if(dd->max_dofs(VERTEX))
    1311            0 :                         adjust_linear<RegularVertex, TUserData>(vUserData, si, A, b, dd, time);
    1312            0 :                 if(dd->max_dofs(EDGE))
    1313            0 :                         adjust_linear<Edge, TUserData>(vUserData, si, A, b, dd, time);
    1314            0 :                 if(dd->max_dofs(FACE))
    1315            0 :                         adjust_linear<Face, TUserData>(vUserData, si, A, b, dd, time);
    1316            0 :                 if(dd->max_dofs(VOLUME))
    1317            0 :                         adjust_linear<Volume, TUserData>(vUserData, si, A, b, dd, time);
    1318              :                 }
    1319            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_linear:"
    1320              :                                                 " While calling 'adjust_linear' for TUserData, aborting.");
    1321              :         }
    1322            0 : }
    1323              : 
    1324              : template <typename TDomain, typename TAlgebra>
    1325              : template <typename TBaseElem, typename TUserData>
    1326            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1327              : adjust_linear(const std::vector<TUserData*>& vUserData, int si,
    1328              :               matrix_type& A, vector_type& b,
    1329              :               ConstSmartPtr<DoFDistribution> dd, number time)
    1330              : {
    1331              : //      create Multiindex
    1332              :         std::vector<DoFIndex> multInd;
    1333              : 
    1334              : //      readin value
    1335              :         typename TUserData::value_type val;
    1336              : 
    1337              : //      save all dirichlet degree of freedom indices.
    1338              :         std::set<size_t> dirichletDoFIndices;
    1339              : 
    1340              : //      position of dofs
    1341              :         std::vector<position_type> vPos;
    1342              : 
    1343              : //      iterators
    1344              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
    1345            0 :         iter = dd->begin<TBaseElem>(si);
    1346            0 :         iterEnd = dd->end<TBaseElem>(si);
    1347              : 
    1348              : //      loop elements
    1349            0 :         for( ; iter != iterEnd; iter++)
    1350              :         {
    1351              :         //      get vertex
    1352              :                 TBaseElem* elem = *iter;
    1353              : 
    1354              :         //      loop dirichlet functions on this segment
    1355            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
    1356              :                 {
    1357            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1358              :                         {
    1359              :                         //      get function index
    1360            0 :                                 const size_t fct = vUserData[i]->fct[f];
    1361              : 
    1362              :                         //      get local finite element id
    1363              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
    1364              : 
    1365              :                         //      get dof position
    1366            0 :                                 InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
    1367              : 
    1368              :                         //      get multi indices
    1369            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
    1370              : 
    1371              :                                 UG_ASSERT(multInd.size() == vPos.size(),
    1372              :                                                   "Mismatch: numInd="<<multInd.size()<<", numPos="
    1373              :                                                   <<vPos.size()<<" on "<<elem->reference_object_id());
    1374              : 
    1375              :                         //      loop dofs on element
    1376            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
    1377              :                                 {
    1378              :                                 //      check if function is dirichlet and read value
    1379            0 :                                         if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
    1380              : 
    1381            0 :                                         this->m_spAssTuner->set_dirichlet_row(A, multInd[j]);
    1382              : 
    1383            0 :                                         if(m_bDirichletColumns)
    1384              :                                         {
    1385              :                                                 // FIXME: Beware, this is dangerous!
    1386              :                                                 //        It will not work for blocked algebras.
    1387            0 :                                                 UG_COND_THROW(multInd[j][1] != 0,
    1388              :                                                         "adjust_linear() is not implemented for block matrices and the symmetric case!");
    1389              :                                                 dirichletDoFIndices.insert(multInd[j][0]);
    1390              :                                         }
    1391              : 
    1392              :                                         if (TUserData::setSolValue)
    1393            0 :                                                 this->m_spAssTuner->set_dirichlet_val(b, multInd[j], val[f]);
    1394              :                                 }
    1395              :                         }
    1396              :                 }
    1397              :         }
    1398              : 
    1399              : 
    1400              : 
    1401            0 :         if(m_bDirichletColumns){
    1402              : //              UG_LOG("adjust linear\n")
    1403            0 :                 m_A = &A;
    1404              :                 // number of rows
    1405              :                 size_t nr = A.num_rows();
    1406              : 
    1407              :                 typename std::set<size_t>::iterator currentDIndex;
    1408              : 
    1409              :                 // run over all rows of the local matrix J and save the column
    1410              :                 // entries for the Dirichlet indices in the map
    1411              : 
    1412            0 :                 for(size_t i = 0; i<nr; i++)
    1413              :                 {
    1414              :                         // do not save any entries in Dirichlet rows!
    1415            0 :                         if (dirichletDoFIndices.find(i) != dirichletDoFIndices.end())
    1416            0 :                                 continue;
    1417              : 
    1418            0 :                         for(typename matrix_type::row_iterator it = A.begin_row(i); it!=A.end_row(i); ++it)
    1419              :                         {
    1420              :                                 currentDIndex = dirichletDoFIndices.find(it.index());
    1421              : 
    1422              :                                 // fill dirichletMap & set corresponding entry to zero
    1423            0 :                                 if(currentDIndex != dirichletDoFIndices.end()){
    1424              : 
    1425              :                                         // the dirichlet-dof-index it.index is assigned
    1426              :                                         // the row i and the matrix entry it.value().
    1427            0 :                                         m_dirichletMap[si][i][it.index()] = it.value();
    1428            0 :                                         it.value() = 0.0;
    1429              :                                 }
    1430              :                         }
    1431              :                 }
    1432              : 
    1433              :                 // TODO: for better efficiency use vectors instead of maps (rows and columns are ordered!)
    1434              :                 typename std::map<int, std::map<int, value_type> >::iterator itdirichletMap;
    1435              :                 typename std::map<int, value_type>::iterator itdirichletRowMap;
    1436            0 :                 for(size_t i = 0; i<nr; i++)
    1437              :                 {
    1438              :                         // step over if this row did not contain any connections to Dirichlet nodes
    1439            0 :                         if ((itdirichletMap = m_dirichletMap[si].find(i)) == m_dirichletMap[si].end())
    1440            0 :                                 continue;
    1441              : 
    1442            0 :                         for(typename matrix_type::row_iterator it = m_A->begin_row(i); it!=m_A->end_row(i); ++it){
    1443              : 
    1444              :                                 // current column index is a dirichlet index
    1445            0 :                                 if ((itdirichletRowMap = itdirichletMap->second.find(it.index())) != itdirichletMap->second.end())
    1446            0 :                                         b[i] -= itdirichletRowMap->second*b[it.index()];
    1447              :                         }
    1448              :                 }
    1449              :         }
    1450            0 : }
    1451              : 
    1452              : ////////////////////////////////////////////////////////////////////////////////
    1453              : //      adjust RHS
    1454              : ////////////////////////////////////////////////////////////////////////////////
    1455              : 
    1456              : template <typename TDomain, typename TAlgebra>
    1457            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1458              : adjust_rhs(vector_type& b, const vector_type& u,
    1459              :            ConstSmartPtr<DoFDistribution> dd, int type, number time)
    1460              : {
    1461            0 :         extract_data();
    1462              : 
    1463            0 :         adjust_rhs<CondNumberData>(m_mBNDNumberBndSegment, b, u, dd, time);
    1464            0 :         adjust_rhs<NumberData>(m_mNumberBndSegment, b, u, dd, time);
    1465            0 :         adjust_rhs<ConstNumberData>(m_mConstNumberBndSegment, b, u, dd, time);
    1466              : 
    1467            0 :         adjust_rhs<VectorData>(m_mVectorBndSegment, b, u, dd, time);
    1468              : 
    1469            0 :         adjust_rhs<OldNumberData>(m_mOldNumberBndSegment, b, u, dd, time);
    1470            0 : }
    1471              : 
    1472              : 
    1473              : template <typename TDomain, typename TAlgebra>
    1474              : template <typename TUserData>
    1475            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1476              : adjust_rhs(const std::map<int, std::vector<TUserData*> >& mvUserData,
    1477              :            vector_type& b, const vector_type& u,
    1478              :            ConstSmartPtr<DoFDistribution> dd, number time)
    1479              : {
    1480              : //      loop boundary subsets
    1481              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
    1482            0 :         for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
    1483              :         {
    1484              :         //      get subset index
    1485            0 :                 const int si = (*iter).first;
    1486              : 
    1487              :         //      get vector of scheduled dirichlet data on this subset
    1488            0 :                 const std::vector<TUserData*>& vUserData = (*iter).second;
    1489              : 
    1490              :         //      adapt jacobian for dofs in each base element type
    1491              :                 try
    1492              :                 {
    1493            0 :                 if(dd->max_dofs(VERTEX))
    1494            0 :                         adjust_rhs<RegularVertex, TUserData>(vUserData, si, b, u, dd, time);
    1495            0 :                 if(dd->max_dofs(EDGE))
    1496            0 :                         adjust_rhs<Edge, TUserData>(vUserData, si, b, u, dd, time);
    1497            0 :                 if(dd->max_dofs(FACE))
    1498            0 :                         adjust_rhs<Face, TUserData>(vUserData, si, b, u, dd, time);
    1499            0 :                 if(dd->max_dofs(VOLUME))
    1500            0 :                         adjust_rhs<Volume, TUserData>(vUserData, si, b, u, dd, time);
    1501              :                 }
    1502            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_rhs:"
    1503              :                                                 " While calling 'adjust_rhs' for TUserData, aborting.");
    1504              :         }
    1505            0 : }
    1506              : 
    1507              : template <typename TDomain, typename TAlgebra>
    1508              : template <typename TBaseElem, typename TUserData>
    1509            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1510              : adjust_rhs(const std::vector<TUserData*>& vUserData, int si,
    1511              :            vector_type& b, const vector_type& u,
    1512              :            ConstSmartPtr<DoFDistribution> dd, number time)
    1513              : {
    1514              : //      create Multiindex
    1515              :         std::vector<DoFIndex> multInd;
    1516              : 
    1517              : //      readin value
    1518              :         typename TUserData::value_type val;
    1519              : 
    1520              : //      position of dofs
    1521              :         std::vector<position_type> vPos;
    1522              : 
    1523              : //      iterators
    1524              :         typename DoFDistribution::traits<TBaseElem>::const_iterator iter, iterEnd;
    1525            0 :         iter = dd->begin<TBaseElem>(si);
    1526            0 :         iterEnd = dd->end<TBaseElem>(si);
    1527              : 
    1528              : //      loop elements
    1529            0 :         for( ; iter != iterEnd; iter++)
    1530              :         {
    1531              :         //      get vertex
    1532              :                 TBaseElem* elem = *iter;
    1533              : 
    1534              :         //      loop dirichlet functions on this segment
    1535            0 :                 for(size_t i = 0; i < vUserData.size(); ++i)
    1536              :                 {
    1537            0 :                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1538              :                         {
    1539              :                         //      get function index
    1540            0 :                                 const size_t fct = vUserData[i]->fct[f];
    1541              : 
    1542              :                         //      get local finite element id
    1543              :                                 const LFEID& lfeID = dd->local_finite_element_id(fct);
    1544              : 
    1545              :                         //      get dof position
    1546            0 :                                 InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
    1547              : 
    1548              :                         //      get multi indices
    1549            0 :                                 dd->inner_dof_indices(elem, fct, multInd);
    1550              : 
    1551              :                                 UG_ASSERT(multInd.size() == vPos.size(), "Size mismatch");
    1552              : 
    1553              :                         //      loop dofs on element
    1554            0 :                                 for(size_t j = 0; j < multInd.size(); ++j)
    1555              :                                 {
    1556              :                                 //      check if function is dirichlet and read value
    1557            0 :                                         if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
    1558              : 
    1559              :                                         if (TUserData::setSolValue)
    1560            0 :                                                 this->m_spAssTuner->set_dirichlet_val(b, multInd[j], val[f]);
    1561              :                                         else
    1562            0 :                                                 this->m_spAssTuner->set_dirichlet_val(b, multInd[j], DoFRef(u, multInd[j]));
    1563              :                                 }
    1564              :                         }
    1565              :                 }
    1566              : 
    1567              :         }
    1568              : 
    1569              : 
    1570              :         // adjust the right hand side
    1571            0 :         if(m_bDirichletColumns){
    1572              :                 typename std::map<int, std::map<int, value_type> >::iterator itdirichletMap;
    1573              :                 typename std::map<int, value_type>::iterator itdirichletRowMap;
    1574            0 :                 size_t nr = m_A->num_rows();
    1575            0 :                 for(size_t i = 0; i<nr; i++)
    1576              :                 {
    1577              :                         // step over if this row did not contain any connections to Dirichlet nodes
    1578            0 :                         if ((itdirichletMap = m_dirichletMap[si].find(i)) == m_dirichletMap[si].end())
    1579            0 :                                 continue;
    1580              : 
    1581            0 :                         for(typename matrix_type::row_iterator it = m_A->begin_row(i); it!=m_A->end_row(i); ++it){
    1582              : 
    1583              :                                 // current column index is a dirichlet index
    1584            0 :                                 if ((itdirichletRowMap = itdirichletMap->second.find(it.index())) != itdirichletMap->second.end())
    1585            0 :                                         b[i] -= itdirichletRowMap->second*b[it.index()];
    1586              :                         }
    1587              :                 }
    1588              :         }
    1589            0 : }
    1590              : 
    1591              : 
    1592              : // //////////////////////////////////////////////////////////////////////////////
    1593              : //      adjust error
    1594              : // //////////////////////////////////////////////////////////////////////////////
    1595              : 
    1596              : template <typename TDomain, typename TAlgebra>
    1597            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1598              : adjust_error
    1599              : (
    1600              :         const vector_type& u,
    1601              :         ConstSmartPtr<DoFDistribution> dd,
    1602              :         int type,
    1603              :         number time,
    1604              :         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1605              :         const std::vector<number>* vScaleMass,
    1606              :         const std::vector<number>* vScaleStiff
    1607              : )
    1608              : {
    1609              :         //      get the error estimator data object and check that it is of the right type
    1610            0 :         if (this->m_spErrEstData.get() == NULL)
    1611              :         {
    1612            0 :                 UG_THROW("No ErrEstData object has been given to this constraint!");
    1613              :         }
    1614              : 
    1615            0 :         err_est_type* err_est_data = dynamic_cast<err_est_type*>(this->m_spErrEstData.get());
    1616              : 
    1617            0 :         if (!err_est_data)
    1618              :         {
    1619            0 :                 UG_THROW("Dynamic cast to MultipleSideAndElemErrEstData failed."
    1620              :                                 << std::endl << "Make sure you handed the correct type of ErrEstData to this discretization.");
    1621              :         }
    1622              : 
    1623              : 
    1624            0 :         extract_data();
    1625              : 
    1626            0 :         adjust_error<CondNumberData>(m_mBNDNumberBndSegment, u, dd, time);
    1627            0 :         adjust_error<NumberData>(m_mNumberBndSegment, u, dd, time);
    1628            0 :         adjust_error<ConstNumberData>(m_mConstNumberBndSegment, u, dd, time);
    1629              :         
    1630            0 :         adjust_error<VectorData>(m_mVectorBndSegment, u, dd, time);
    1631              :         
    1632            0 :         adjust_error<OldNumberData>(m_mOldNumberBndSegment, u, dd, time);
    1633            0 : }
    1634              : 
    1635              : template <typename TDomain, typename TAlgebra>
    1636              : template <typename TUserData>
    1637            0 : void DirichletBoundary<TDomain, TAlgebra>::
    1638              : adjust_error
    1639              : (
    1640              :         const std::map<int, std::vector<TUserData*> >& mvUserData,
    1641              :         const vector_type& u,
    1642              :         ConstSmartPtr<DoFDistribution> dd,
    1643              :         number time
    1644              : )
    1645              : {
    1646              :         // cast error estimator data object to the right type
    1647            0 :         err_est_type* err_est_data = dynamic_cast<err_est_type*>(this->m_spErrEstData.get());
    1648              : 
    1649              :         typedef typename err_est_type::side_type side_type;
    1650              : 
    1651              :         // loop boundary subsets
    1652              :         typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
    1653            0 :         for (iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
    1654              :         {
    1655              :                 // get subset index
    1656            0 :                 const int si = (*iter).first;
    1657              : 
    1658              :                 // get vector of scheduled dirichlet data on this subset
    1659              :                 const std::vector<TUserData*>& vUserData = (*iter).second;
    1660              : 
    1661              :                 try
    1662              :                 {
    1663              :                         // create multi-index
    1664              :                         std::vector<DoFIndex> multInd;
    1665              : 
    1666              :                         // dummy for readin
    1667              :                         typename TUserData::value_type val;
    1668              : 
    1669              :                         // position of dofs
    1670              :                         std::vector<position_type> vPos;
    1671              : 
    1672              :                         // iterators
    1673              :                         typename DoFDistribution::traits<side_type>::const_iterator iter, iterEnd;
    1674            0 :                         iter = dd->begin<side_type>(si);
    1675            0 :                         iterEnd = dd->end<side_type>(si);
    1676              : 
    1677              :                         // loop elements of side_type (only!)
    1678              :                         // elements of measure 0 in the boundary are ignored.
    1679            0 :                         for( ; iter != iterEnd; iter++)
    1680              :                         {
    1681              :                                 // get vertex
    1682              :                                 side_type* elem = *iter;
    1683              : 
    1684              :                                 // get reference object id
    1685            0 :                                 ReferenceObjectID roid = elem->reference_object_id();
    1686              : 
    1687              :                                 // get corner coords (for later use in calculating global IPs)
    1688              :                                 std::vector<typename TDomain::position_type> vCoCo;
    1689              :                                 CollectCornerCoordinates(vCoCo, elem, *m_spDomain, false);
    1690              : 
    1691              :                                 // loop dirichlet functions on this segment
    1692            0 :                                 for(size_t i = 0; i < vUserData.size(); ++i)
    1693              :                                 {
    1694            0 :                                         for(size_t f = 0; f < TUserData::numFct; ++f)
    1695              :                                         {
    1696              :                                                 // get function index
    1697            0 :                                                 const size_t fct = vUserData[i]->fct[f];
    1698              : 
    1699              :                                                 // get lfeID for function
    1700            0 :                                                 LFEID lfeID = dd->local_finite_element_id(fct);
    1701              : 
    1702              :                                                 // get local and global IPs
    1703              :                                                 size_t numSideIPs;
    1704              :                                                 const MathVector<side_type::dim>* sideLocIPs;
    1705              :                                                 const MathVector<dim>* sideGlobIPs;
    1706              : 
    1707              :                                                 try
    1708              :                                                 {
    1709            0 :                                                         numSideIPs = err_est_data->get(fct)->num_side_ips(roid);
    1710            0 :                                                         sideLocIPs = err_est_data->get(fct)->template side_local_ips<side_type::dim>(roid);
    1711            0 :                                                         sideGlobIPs = err_est_data->get(fct)->side_global_ips(elem, &vCoCo[0]);
    1712              :                                                 }
    1713            0 :                                                 UG_CATCH_THROW("Global integration points for error estimator cannot be determined.");
    1714              : 
    1715              :                                                 // loop IPs
    1716            0 :                                                 for (size_t ip = 0; ip < numSideIPs; ++ip)
    1717              :                                                 {
    1718              :                                                         // get Dirichlet value (and do nothing, if conditional D value is false)
    1719            0 :                                                         if (!(*vUserData[i])(val, sideGlobIPs[ip], time, si)) continue;
    1720              :                                                         
    1721              :                                                         // check if we take the values directly from the solution
    1722              :                                                         if (! TUserData::setSolValue)
    1723              :                                                         {
    1724            0 :                                                                 (*err_est_data->get(fct))(elem,ip) = 0;
    1725              :                                                                 continue;
    1726              :                                                         }
    1727              : 
    1728              :                                                         // evaluate shapes at ip
    1729            0 :                                                         LFEID new_lfeID(lfeID.type(), lfeID.dim()-1, lfeID.order());
    1730              :                                                         const LocalShapeFunctionSet<side_type::dim>& rTrialSpace =
    1731              :                                                                 LocalFiniteElementProvider::get<side_type::dim>(roid, new_lfeID);
    1732              :                                                         std::vector<number> vShape;
    1733            0 :                                                         rTrialSpace.shapes(vShape, sideLocIPs[ip]);
    1734              : 
    1735              :                                                         // get multiindices of element
    1736              :                                                         std::vector<DoFIndex> ind;
    1737            0 :                                                         dd->dof_indices(elem, fct, ind);
    1738              : 
    1739              :                                                         // compute solution at integration point
    1740              :                                                         number uAtIP = 0.0;
    1741            0 :                                                         for (size_t sh = 0; sh < vShape.size(); ++sh)
    1742            0 :                                                                 uAtIP += DoFRef(u, ind[sh]) * vShape[sh];
    1743              : 
    1744              :                                                         // set error integrand value at IP
    1745            0 :                                                         (*err_est_data->get(fct))(elem,ip) = val[f] - uAtIP;
    1746              :                                                 }
    1747              :                                         }
    1748              :                                 }
    1749              :                         }
    1750            0 :                 }
    1751            0 :                 UG_CATCH_THROW("DirichletBoundary::adjust_error:"
    1752              :                                                 " While calling 'adjust_error' for TUserData, aborting.");
    1753              :         }
    1754            0 : }
    1755              : 
    1756              : 
    1757              : } // end namespace ug
    1758              : 
    1759              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__LAGRANGE_DIRICHLET_BOUNDARY_IMPL__ */
        

Generated by: LCOV version 2.0-1