LCOV - code coverage report
Current view: top level - ugbase/lib_disc/function_spaces - approximation_space.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 353 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 44 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              : #include "approximation_space.h"
      34              : #include "lib_disc/domain.h"
      35              : #include "lib_disc/common/groups_util.h"
      36              : #include "common/util/string_util.h"
      37              : #include "common/profiler/profiler.h"
      38              : 
      39              : #ifdef UG_PARALLEL
      40              :         #include "pcl/pcl.h"
      41              : #endif
      42              : 
      43              : #include "lib_disc/dof_manager/dof_distribution.h"
      44              : #include "grid_function.h"
      45              : 
      46              : #include <algorithm> // std::sort
      47              : #include <sstream> // std::stringstream
      48              : using namespace std;
      49              : 
      50              : //      for debugging only:
      51              : //#include "lib_grid/file_io/file_io.h"
      52              : //#define APPROX_SPACE_PERFORM_CHANGED_GRID_DEBUG_SAVES
      53              : //#define APPROX_SPACE_PERFORM_DISTRIBUTED_GRID_DEBUG_SAVES
      54              : 
      55              : namespace ug{
      56              : 
      57              : ////////////////////////////////////////////////////////////////////////////////
      58              : // IApproximationSpace
      59              : ////////////////////////////////////////////////////////////////////////////////
      60              : 
      61            0 : IApproximationSpace::
      62              : IApproximationSpace(SmartPtr<subset_handler_type> spMGSH,
      63              :                     SmartPtr<grid_type> spMG,
      64            0 :                     const AlgebraType& algebraType)
      65              : {
      66            0 :         init(spMGSH, spMG, algebraType);
      67            0 : }
      68              : 
      69            0 : IApproximationSpace::
      70              : IApproximationSpace(SmartPtr<subset_handler_type> spMGSH,
      71            0 :                     SmartPtr<grid_type> spMG)
      72              : {
      73            0 :         init(spMGSH, spMG, DefaultAlgebra::get());
      74            0 : }
      75              : 
      76            0 : void IApproximationSpace::
      77              : init(SmartPtr<subset_handler_type> spMGSH,
      78              :      SmartPtr<grid_type> spMG,
      79              :      const AlgebraType& algebraType)
      80              : {
      81            0 :         m_spMG = spMG;
      82            0 :         m_spMGSH = spMGSH;
      83            0 :         m_spDoFDistributionInfo = SmartPtr<DoFDistributionInfo>(new DoFDistributionInfo(spMGSH));
      84            0 :         m_algebraType = algebraType;
      85            0 :         m_bAdaptionIsActive = false;
      86            0 :         m_RevCnt = RevisionCounter(this);
      87              : 
      88            0 :         this->set_dof_distribution_info(m_spDoFDistributionInfo);
      89              : 
      90              : //      get blocksize of algebra
      91              :         const int blockSize = m_algebraType.blocksize();
      92              : 
      93              : //      a)      If blocksize fixed and > 1, we need grouping in dof manager. Thus,
      94              : //              the dofmanager hopefully fits (i.e. same number of grouped
      95              : //              dofs everywhere.)
      96            0 :         if(blockSize > 1) m_bGrouped = true;
      97              : //      b)      If blocksize flexible, we group
      98            0 :         else if (blockSize == AlgebraType::VariableBlockSize) m_bGrouped = true;
      99              : //      c)      If blocksize == 1, we do not group. This will allow us to handle
     100              : //              this case for any problem.
     101            0 :         else if (blockSize == 1) m_bGrouped = false;
     102              :         else
     103            0 :                 UG_THROW("Cannot determine blocksize of Algebra.");
     104              : 
     105              : //      this class listens to the grid-adaption-messages
     106            0 :         register_at_adaption_msg_hub();
     107            0 : }
     108              : 
     109              : 
     110            0 : IApproximationSpace::
     111              : ~IApproximationSpace()
     112              : {
     113            0 :         if(m_spSurfaceView.valid())
     114            0 :                 m_spSurfaceView = SmartPtr<SurfaceView>(NULL);
     115            0 : }
     116              : 
     117              : template <typename TElem>
     118            0 : bool MightContainGhosts(const GridLayoutMap& layoutMap, int lvl)
     119              : {
     120            0 :         if(!layoutMap.has_layout<TElem>(INT_V_MASTER)) return false;
     121            0 :         if(lvl >= (int)layoutMap.get_layout<TElem>(INT_V_MASTER).num_levels()) return false;
     122            0 :         if(layoutMap.get_layout<TElem>(INT_V_MASTER).empty(lvl)) return false;
     123              : 
     124              :         typedef typename GridLayoutMap::Types<TElem>::Layout::LevelLayout TLayout;
     125              :         typedef typename TLayout::const_iterator InterfaceIterator;
     126              : 
     127            0 :         const TLayout& elemLayout = layoutMap.get_layout<TElem>(INT_V_MASTER).layout_on_level(lvl);
     128            0 :         for(InterfaceIterator iIter = elemLayout.begin(); iIter != elemLayout.end(); ++iIter){
     129            0 :                 if(!elemLayout.interface(iIter).empty())
     130              :                         return true;
     131              :         }
     132              : 
     133              :         return false;
     134              : }
     135              : 
     136            0 : bool IApproximationSpace::might_contain_ghosts(int lvl) const
     137              : {
     138            0 :         if(lvl < 0 || lvl > (int)num_levels()-1)
     139            0 :                 UG_THROW("ApproximationSpace: Level not contained.");
     140              : 
     141              :         const DistributedGridManager* pDistGridMgr = m_spMG->distributed_grid_manager();
     142            0 :         if(!pDistGridMgr) return false;
     143              : 
     144              :         bool bGhosts = false;
     145              :         const GridLayoutMap& layoutMap = pDistGridMgr->grid_layout_map();
     146            0 :         if(max_dofs(VERTEX)) bGhosts |=  MightContainGhosts<Vertex>(layoutMap, lvl);
     147            0 :         if(max_dofs(EDGE)) bGhosts |=  MightContainGhosts<Edge>(layoutMap, lvl);
     148            0 :         if(max_dofs(FACE)) bGhosts |=  MightContainGhosts<Face>(layoutMap, lvl);
     149            0 :         if(max_dofs(VOLUME)) bGhosts |=  MightContainGhosts<Volume>(layoutMap, lvl);
     150              : 
     151              :         return bGhosts;
     152              : }
     153              : 
     154            0 : bool IApproximationSpace::might_contain_ghosts() const
     155              : {
     156              :         bool bGhosts = false;
     157            0 :         for(int lvl = 0; lvl < (int)num_levels(); ++lvl)
     158            0 :                 bGhosts |= might_contain_ghosts(lvl);
     159              : 
     160            0 :         return bGhosts;
     161              : }
     162              : 
     163              : ////////////////////////////////////////////////////////////////////////////////
     164              : // add
     165              : ////////////////////////////////////////////////////////////////////////////////
     166              : 
     167            0 : void IApproximationSpace::
     168              : add(const std::vector<std::string>& vName, const char* fetype, int order)
     169              : {
     170            0 :         const int dim = DimensionOfSubsets(*m_spMGSH);
     171            0 :         if(dim == DIM_SUBSET_EMPTY_GRID)
     172            0 :                 UG_THROW("ApproximationSpace: Cannot find dimension of grid. Maybe your grid is empty?");
     173              : 
     174            0 :         add(vName, ConvertStringToLFEID(fetype, dim, order));
     175            0 : }
     176              : 
     177            0 : void IApproximationSpace::
     178              : add(const std::vector<std::string>& vName, const char* fetype)
     179              : {
     180            0 :         const int dim = DimensionOfSubsets(*m_spMGSH);
     181            0 :         if(dim == DIM_SUBSET_EMPTY_GRID)
     182            0 :                 UG_THROW("ApproximationSpace: Cannot find dimension of grid. Maybe your grid is empty?");
     183              : 
     184            0 :         add(vName, ConvertStringToLFEID(fetype, dim));
     185            0 : }
     186              : 
     187            0 : void IApproximationSpace::
     188              : add(const char* name, const char* fetype, int order)
     189              : {
     190            0 :         add(TokenizeTrimString(name), fetype, order);
     191            0 : }
     192              : 
     193            0 : void IApproximationSpace::
     194              : add(const char* name, const char* fetype)
     195              : {
     196            0 :         add(TokenizeTrimString(name), fetype);
     197            0 : }
     198              : 
     199              : 
     200            0 : void IApproximationSpace::
     201              : add(const std::vector<std::string>& vName, const char* fetype, int order,
     202              :     const std::vector<std::string>& vSubsets)
     203              : {
     204            0 :         SubsetGroup ssGrp(m_spMGSH, vSubsets);
     205            0 :         const int dim = ssGrp.get_highest_subset_dimension();
     206              : 
     207              : //      check
     208            0 :         if(dim == DIM_SUBSET_EMPTY_GRID)
     209            0 :                 UG_THROW("ApproximationSpace: Cannot find dimension for new function on"
     210              :                                 "the subsets. Maybe your grid is empty?");
     211              : 
     212            0 :         add(vName, ConvertStringToLFEID(fetype, dim, order), vSubsets);
     213            0 : }
     214              : 
     215            0 : void IApproximationSpace::
     216              : add(const std::vector<std::string>& vName, const char* fetype,
     217              :     const std::vector<std::string>& vSubsets)
     218              : {
     219            0 :         SubsetGroup ssGrp(m_spMGSH, vSubsets);
     220            0 :         const int dim = ssGrp.get_highest_subset_dimension();
     221              : 
     222              : //      check
     223            0 :         if(dim == DIM_SUBSET_EMPTY_GRID)
     224            0 :                 UG_THROW("ApproximationSpace: Cannot find dimension for new function on"
     225              :                                 "the subsets. Maybe your grid is empty?");
     226              : 
     227            0 :         add(vName, ConvertStringToLFEID(fetype, dim), vSubsets);
     228            0 : }
     229              : 
     230            0 : void IApproximationSpace::
     231              : add(const char* name, const char* fetype, int order, const char* subsets)
     232              : {
     233            0 :         add(TokenizeTrimString(name), fetype, order, TokenizeTrimString(subsets));
     234            0 : }
     235              : 
     236            0 : void IApproximationSpace::
     237              : add(const char* name, const char* fetype, const char* subsets)
     238              : {
     239            0 :         add(TokenizeTrimString(name), fetype, TokenizeTrimString(subsets));
     240            0 : }
     241              : 
     242              : ////////////////////////////////////////////////////////////////////////////////
     243              : // DoFDistributions
     244              : ////////////////////////////////////////////////////////////////////////////////
     245              : 
     246              : SmartPtr<DoFDistribution>
     247            0 : IApproximationSpace::dof_distribution(const GridLevel& gl, bool bCreate)
     248              : {
     249            0 :         for(size_t i = 0; i < m_vDD.size(); ++i)
     250              :                 if(m_vDD[i]->grid_level() == gl)
     251              :                         return m_vDD[i];
     252              : 
     253            0 :         if(!bCreate)
     254            0 :                 UG_THROW("ApproxSpace: Could not create the DoFDistribution to GridLevel "<<gl);
     255              : 
     256            0 :         create_dof_distribution(gl);
     257              : 
     258            0 :         return dof_distribution(gl, false);
     259              : }
     260              : 
     261              : SmartPtr<DoFDistribution>
     262            0 : IApproximationSpace::dd(const GridLevel& gl, bool bCreate)
     263              : {
     264            0 :         return dof_distribution(gl, bCreate);
     265              : }
     266              : 
     267              : ConstSmartPtr<DoFDistribution>
     268            0 : IApproximationSpace::dof_distribution(const GridLevel& gl, bool bCreate) const
     269              : {
     270            0 :         return const_cast<IApproximationSpace*>(this)->dof_distribution(gl, bCreate);
     271              : }
     272              : 
     273              : ConstSmartPtr<DoFDistribution>
     274            0 : IApproximationSpace::dd(const GridLevel& gl, bool bCreate) const
     275              : {
     276            0 :         return dof_distribution(gl, bCreate);
     277              : }
     278              : 
     279              : std::vector<SmartPtr<DoFDistribution> >
     280            0 : IApproximationSpace::dof_distributions() const
     281              : {
     282            0 :         return m_vDD;
     283              : }
     284              : 
     285              : 
     286            0 : void IApproximationSpace::init_levels()
     287              : {
     288              :         PROFILE_FUNC();
     289            0 :         for(size_t lvl = 0; lvl < num_levels(); ++lvl){
     290            0 :                 dof_distribution(GridLevel(lvl, GridLevel::LEVEL, false));
     291            0 :                 dof_distribution(GridLevel(lvl, GridLevel::LEVEL, true));
     292              :         }
     293            0 : }
     294              : 
     295            0 : void IApproximationSpace::init_surfaces()
     296              : {
     297              :         PROFILE_FUNC();
     298            0 :         for(size_t lvl = 0; lvl < num_levels(); ++lvl)
     299            0 :                 dof_distribution(GridLevel(lvl, GridLevel::SURFACE, false));
     300              : 
     301            0 :         init_top_surface();
     302            0 : }
     303              : 
     304            0 : void IApproximationSpace::init_top_surface()
     305              : {
     306              :         PROFILE_FUNC();
     307            0 :         dof_distribution(GridLevel(GridLevel::TOP, GridLevel::SURFACE, false));
     308            0 : }
     309              : 
     310              : ////////////////////////////////////////////////////////////////////////////////
     311              : // DoFDistribution Creation
     312              : ////////////////////////////////////////////////////////////////////////////////
     313              : 
     314            0 : bool SortDD(SmartPtr<DoFDistribution> spDD1, SmartPtr<DoFDistribution> spDD2){
     315            0 :         return spDD1->grid_level() < spDD2->grid_level();
     316              : }
     317              : 
     318            0 : void IApproximationSpace::create_dof_distribution(const GridLevel& gl)
     319              : {
     320              : 
     321            0 :         dof_distribution_info_required();
     322            0 :         surface_view_required();
     323              : 
     324              : //      get DoFIndexStorage if it is reusable
     325              :         SmartPtr<DoFIndexStorage> spIndexStrg;
     326            0 :         if(gl.is_level()){
     327            0 :                 if(gl.ghosts()){
     328            0 :                         if(m_spDoFIndexStrgForLevelWithGhost.invalid())
     329            0 :                                 m_spDoFIndexStrgForLevelWithGhost = SmartPtr<DoFIndexStorage>(
     330            0 :                                                 new DoFIndexStorage(m_spMG, m_spDoFDistributionInfo));
     331            0 :                         spIndexStrg = m_spDoFIndexStrgForLevelWithGhost;
     332              :                 }
     333              :                 else{
     334            0 :                         if(m_spDoFIndexStrgForLevelNoGhost.invalid())
     335            0 :                                 m_spDoFIndexStrgForLevelNoGhost = SmartPtr<DoFIndexStorage>(
     336            0 :                                                 new DoFIndexStorage(m_spMG, m_spDoFDistributionInfo));
     337            0 :                         spIndexStrg = m_spDoFIndexStrgForLevelNoGhost;
     338              :                 }
     339              :         }
     340              : 
     341              : //      create DoFDistribution
     342              :         SmartPtr<DoFDistribution> spDD = SmartPtr<DoFDistribution>(new
     343              :                 DoFDistribution(m_spMG, m_spMGSH, m_spDoFDistributionInfo,
     344            0 :                                                 m_spSurfaceView, gl, m_bGrouped, spIndexStrg));
     345              : 
     346              : //      add to list and sort
     347            0 :         m_vDD.push_back(spDD);
     348            0 :         std::sort(m_vDD.begin(), m_vDD.end(), SortDD);
     349            0 : }
     350              : 
     351            0 : void IApproximationSpace::surface_view_required()
     352              : {
     353              : //      allocate surface view if needed
     354            0 :         if(!m_spSurfaceView.valid())
     355            0 :                 m_spSurfaceView = SmartPtr<SurfaceView>(new SurfaceView(m_spMGSH));
     356            0 : }
     357              : 
     358            0 : void IApproximationSpace::dof_distribution_info_required()
     359              : {
     360              : //      init dd-info (and fix the function pattern by that)
     361            0 :         m_spDoFDistributionInfo->init();
     362              : 
     363              : //      check that used algebra-type matches requirements
     364              : //      get blocksize of algebra
     365              :         const int blockSize = m_algebraType.blocksize();
     366              : 
     367              : //      if blockSize is 1, we're fine if dd is non-grouped
     368            0 :         if(blockSize == 1){
     369            0 :                 if(m_bGrouped == true)
     370            0 :                         UG_THROW("ApproximationSpace: Using grouped DD, but Algebra is 1x1.")
     371              :         }
     372              : 
     373              : //      if variable block algebra
     374            0 :         else if(blockSize == AlgebraType::VariableBlockSize){
     375            0 :                 UG_THROW("ApproximationSpace: Variable algebra currently not supported.")
     376              :         }
     377              : 
     378              : //      if block algebra, check that number of sub-elements is zero or == blockSize
     379            0 :         else if(blockSize > 1){
     380            0 :                 for(int r = 0; r < NUM_REFERENCE_OBJECTS; ++r){
     381              :                         const ReferenceObjectID roid = (ReferenceObjectID)r;
     382              : 
     383            0 :                         for(int si = 0; si < m_spDDI->num_subsets(); ++si){
     384            0 :                                 const int  numDoFs = m_spDDI->num_dofs(roid, si);
     385              : 
     386            0 :                                 if(numDoFs != 0 && numDoFs != blockSize)
     387            0 :                                         UG_THROW("ApproximationSpace: Using Block-Algebra with "
     388              :                                                         "Blocksize "<<blockSize<<". Therefore, the number of"
     389              :                                                         " dofs on each ReferenceObject must equal the blocksize"
     390              :                                                         " or be zero. But number of dofs on "<<roid<<" in "
     391              :                                                         "subset "<<si<<" is "<<numDoFs<<".");
     392              :                         }
     393              :                 }
     394              :         }
     395              : 
     396              : //      catch other (invalid) settings
     397              :         else
     398            0 :                 UG_THROW("Cannot determine blocksize of Algebra.");
     399            0 : }
     400              : 
     401              : ////////////////////////////////////////////////////////////////////////////////
     402              : // Grid-Change Handling
     403              : ////////////////////////////////////////////////////////////////////////////////
     404              : 
     405            0 : void IApproximationSpace::reinit()
     406              : {
     407              :         PROFILE_FUNC();
     408              : //      update surface view
     409            0 :         if(m_spSurfaceView.valid())
     410            0 :                 m_spSurfaceView->refresh_surface_states();
     411              : 
     412              : //      reinit all existing dof distributions
     413            0 :         for(size_t i = 0; i < m_vDD.size(); ++i){
     414            0 :                 m_vDD[i]->reinit();
     415              :         }
     416              : 
     417              : //      increase revision counter
     418            0 :         ++m_RevCnt;
     419            0 : }
     420              : 
     421            0 : void IApproximationSpace::register_at_adaption_msg_hub()
     422              : {
     423              : //      register function for grid adaption
     424              :         SPMessageHub msgHub = m_spMGSH->multi_grid()->message_hub();
     425              :         m_spGridAdaptionCallbackID =
     426            0 :                 msgHub->register_class_callback(this,
     427            0 :                 &ug::IApproximationSpace::grid_changed_callback);
     428              : 
     429              :         m_spGridDistributionCallbackID =
     430            0 :                 msgHub->register_class_callback(this,
     431            0 :                 &ug::IApproximationSpace::grid_distribution_callback);
     432            0 : }
     433              : 
     434            0 : void IApproximationSpace::
     435              : grid_changed_callback(const GridMessage_Adaption& msg)
     436              : {
     437            0 :         if(msg.adaption_begins())
     438            0 :                 m_bAdaptionIsActive = true;
     439              : 
     440            0 :         else if(m_bAdaptionIsActive){
     441            0 :                         if(msg.adaption_ends())
     442              :                         {
     443            0 :                                 reinit();
     444            0 :                                 m_bAdaptionIsActive = false;
     445              : 
     446              :                                 #ifdef APPROX_SPACE_PERFORM_CHANGED_GRID_DEBUG_SAVES
     447              :                                         {
     448              :                                                 static int counter = 0;
     449              :                                                 std::stringstream ss;
     450              :                                                 ss << "grid-changed-surface-view" << counter << "-p" << pcl::ProcRank() << ".ugx";
     451              :                                                 UG_LOG("PERFORMING SURFACE VIEW DEBUG SAVE IN IApproximationSpace::grid_changed_callback: " << ss.str() << "\n");
     452              :                                                 SaveSurfaceViewTransformed(*m_spMG, *m_spSurfaceView, ss.str().c_str(), 0.1);
     453              :                                                 ++counter;
     454              :                                         }
     455              :                                         {
     456              :                                                 #ifdef UG_PARALLEL
     457              :                                                         static int counter = 0;
     458              :                                                         std::stringstream ss;
     459              :                                                         ss << "grid-changed-parallel-layout-" << counter << "-p" << pcl::ProcRank() << ".ugx";
     460              :                                                         UG_LOG("PERFORMING GRID LAYOUT DEBUG SAVE IN IApproximationSpace::grid_changed_callback: " << ss.str() << "\n");
     461              :                                                         SaveParallelGridLayout(*m_spMG, ss.str().c_str(), 0.1);
     462              :                                                         ++counter;
     463              :                                                 #endif
     464              :                                         }
     465              :                                 #endif
     466              :                         }
     467              :         }
     468              : 
     469              :         else{
     470            0 :                 UG_THROW("Before any grid-adaption may be performed, the approximation"
     471              :                                 " space has to be informed that grid-adaption shall begin. "
     472              :                                 "You may use IRefiner::grid_adaption_begins() or schedule "
     473              :                                 "an appropriate message to the associated grids message-hub.");
     474              :         }
     475            0 : }
     476              : 
     477            0 : void IApproximationSpace::
     478              : grid_distribution_callback(const GridMessage_Distribution& msg)
     479              : {
     480              :         PROFILE_FUNC();
     481            0 :         switch(msg.msg()){
     482              :                 case GMDT_DISTRIBUTION_STARTS:
     483              :                         break;
     484              : 
     485            0 :                 case GMDT_DISTRIBUTION_STOPS:
     486            0 :                         reinit();
     487              :                         #ifdef APPROX_SPACE_PERFORM_DISTRIBUTED_GRID_DEBUG_SAVES
     488              :                                 {
     489              :                                         static int counter = 0;
     490              :                                         std::stringstream ss;
     491              :                                         ss << "grid-distributed-surface-view" << counter << "-p" << pcl::ProcRank() << ".ugx";
     492              :                                         UG_LOG("PERFORMING SURFACE VIEW DEBUG SAVE IN IApproximationSpace::grid_distribution_callback: " << ss.str() << "\n");
     493              :                                         SaveSurfaceViewTransformed(*m_spMG, *m_spSurfaceView, ss.str().c_str(), 0.1);
     494              :                                         ++counter;
     495              :                                 }
     496              :                                 {
     497              :                                         #ifdef UG_PARALLEL
     498              :                                                 static int counter = 0;
     499              :                                                 std::stringstream ss;
     500              :                                                 ss << "grid-distributed-parallel-layout-" << counter << "-p" << pcl::ProcRank() << ".ugx";
     501              :                                                 UG_LOG("PERFORMING GRID LAYOUT DEBUG SAVE IN IApproximationSpace::grid_distribution_callback: " << ss.str() << "\n");
     502              :                                                 SaveParallelGridLayout(*m_spMG, ss.str().c_str(), 0.1);
     503              :                                                 ++counter;
     504              :                                         #endif
     505              :                                 }
     506              :                         #endif
     507            0 :                         break;
     508              : 
     509              :                 default:
     510              :                         break;
     511              :         }
     512            0 : }
     513              : 
     514              : ////////////////////////////////////////////////////////////////////////////////
     515              : // Statistic
     516              : ////////////////////////////////////////////////////////////////////////////////
     517              : 
     518            0 : void PrintDoFCount(const vector<DoFCount>& vDC,
     519              :                    const string& sInfo,
     520              :                    const string& sAlgebra,
     521              :                    const string& sflags)
     522              : {
     523              :         const bool bPrintCmps = (sflags.find("component") != string::npos);
     524              :         const bool bPrintInterface = (sflags.find("interface") != string::npos);
     525              :         const bool bPrintSurface = (sflags.find("surface") != string::npos);
     526              :         const bool bPrintSubset = (sflags.find("subset") != string::npos);
     527              : 
     528              : //      check for output
     529            0 :         if(vDC.size() == 0)
     530            0 :                 UG_THROW("Expected something to print.")
     531              : 
     532              : //      constants for size of output
     533              :         static const int LEVEL = 14;
     534              :         static const int COMPONENT = 7;
     535              :         static const int INTERFACE = 8;
     536              :         static const int SURFACE = 12;
     537              :         static const int NUMBER = 12;
     538              :         static const char* sSep = " | ";
     539              :         static const char* sLeft = "| ";
     540              :         static const char* sRight = " |";
     541              : 
     542              : //      constants for selection
     543              :         static const int ALL_FCT = DoFCount::ALL_FCT;
     544              :         static const int ALL_SUBSET = DoFCount::ALL_SUBSET;
     545              :         static const byte ALL_ES = DoFCount::ALL_ES;
     546              :         static const byte ALL_SS = DoFCount::ALL_SS;
     547              :         static const byte UNIQUE_ES = DoFCount::UNIQUE_ES;
     548              :         static const byte UNIQUE_SS = DoFCount::UNIQUE_SS;
     549              : 
     550              : //      Table Header
     551            0 :         stringstream ssHead;
     552            0 :         ssHead << setw(LEVEL) << "GridLevel  " << sSep;
     553              : 
     554              : //      Components
     555              :         vector<pair<string,int> > vCmp;
     556            0 :         vCmp.push_back(pair<string,int>("all", ALL_FCT));
     557            0 :         if(bPrintCmps){
     558            0 :                 ssHead << setw(COMPONENT) << "Comps" << sSep;
     559            0 :                 for(int fct = 0; fct < (int)vDC[0].num_fct(); ++fct){
     560            0 :                         stringstream name; name << fct << ": "<< vDC[0].name(fct);
     561            0 :                         vCmp.push_back(pair<string,int>(SnipString(name.str(), COMPONENT, 2), fct));
     562            0 :                 }
     563              :         }
     564              : 
     565              : //      Interface
     566            0 :         if(bPrintInterface) {
     567            0 :                 ssHead << setw(INTERFACE) << "Parallel" << sSep;
     568              :         }
     569              : 
     570              : //      Surface
     571            0 :         if(bPrintSurface) {
     572            0 :                 ssHead << setw(SURFACE) << "Surface" << sSep;
     573              :         }
     574              : 
     575              : //      Subsets
     576            0 :         ssHead << setw(NUMBER) << "Domain";
     577            0 :         vector<int> vSubset; vSubset.push_back(ALL_SUBSET);
     578            0 :         if(bPrintSubset) {
     579            0 :                 for(int si = 0; si < vDC[0].num_subsets(); ++si){
     580            0 :                         stringstream name; name << si << ": "<< vDC[0].subset_name(si);
     581            0 :                         ssHead << sSep << setw(NUMBER) << SnipString(name.str(), NUMBER, 2);
     582            0 :                         vSubset.push_back(si);
     583            0 :                 }
     584              :         }
     585              : 
     586              : //      size of a line
     587            0 :         int LINE = ssHead.str().size();
     588            0 :         if(LINE < 76) LINE = 76;
     589              : 
     590            0 :         UG_LOG(sLeft << repeat('-', LINE) << sRight << endl);
     591            0 :         UG_LOG(sLeft << left << setw(LINE) << sInfo << right << sRight << endl);
     592            0 :         UG_LOG(sLeft << left << setw(LINE) << sAlgebra << right << sRight << endl);
     593            0 :         UG_LOG(sLeft << setw(LINE) << "" << sRight << endl);
     594            0 :         UG_LOG(sLeft << setw(LINE) << left << ssHead.str() << right << sRight << endl);
     595            0 :         UG_LOG(sLeft << repeat('-', LINE) << sRight << endl);
     596              : 
     597              : 
     598              : //      Loop Level
     599            0 :         for(size_t i = 0; i < vDC.size(); ++i){
     600              : 
     601              :                 const DoFCount& dc = vDC[i];
     602            0 :                 const GridLevel gl = dc.grid_level();
     603            0 :                 stringstream ssGL; ssGL << gl;
     604              : 
     605              :         //      always print unique (w.r.t interface) number
     606              :                 vector<pair<string, byte> > vInIS;
     607            0 :                 vInIS.push_back(pair<string,byte>("unique",UNIQUE_ES));
     608              :                 vector<pair<string, byte> > vContainsIS;
     609              : 
     610              :         //      if PrintInterface: add more output
     611            0 :                 if(bPrintInterface){
     612            0 :                         vContainsIS.push_back(pair<string,byte>("m (&)",ES_H_MASTER));
     613            0 :                         vContainsIS.push_back(pair<string,byte>("s (&)",ES_H_SLAVE));
     614            0 :                         vInIS.push_back(pair<string,byte>("all",ALL_ES));
     615              : 
     616              :                 //      if grid level with ghost: add more output
     617            0 :                         if(gl.is_level() && gl.ghosts()){
     618            0 :                                 vContainsIS.push_back(pair<string,byte>("vm (&)",ES_V_MASTER));
     619            0 :                                 vContainsIS.push_back(pair<string,byte>("vs (&)",ES_V_SLAVE));
     620            0 :                                 vInIS.push_back(pair<string,byte>("no (x)",ES_NONE));
     621            0 :                                 vInIS.push_back(pair<string,byte>("m (x)",ES_H_MASTER));
     622            0 :                                 vInIS.push_back(pair<string,byte>("s (x)",ES_H_SLAVE));
     623            0 :                                 vInIS.push_back(pair<string,byte>("vm (x)",ES_V_MASTER));
     624            0 :                                 vInIS.push_back(pair<string,byte>("vs (x)", ES_V_SLAVE));
     625            0 :                                 vInIS.push_back(pair<string,byte>("m+vm (x)", ES_H_MASTER | ES_V_MASTER));
     626            0 :                                 vInIS.push_back(pair<string,byte>("m+vs (x)", ES_H_MASTER | ES_V_SLAVE));
     627            0 :                                 vInIS.push_back(pair<string,byte>("s+vm (x)", ES_H_SLAVE | ES_V_MASTER));
     628            0 :                                 vInIS.push_back(pair<string,byte>("s+vs (x)", ES_H_SLAVE | ES_V_SLAVE));
     629              :                         }
     630              :                 }
     631              : 
     632              :         //      always print unique (w.r.t. surface) number
     633              :                 vector<pair<string, byte> > vInSS;
     634            0 :                 if(gl.is_surface())
     635            0 :                         vInSS.push_back(pair<string,byte>("unique",UNIQUE_SS));
     636              :                 else
     637            0 :                         vInSS.push_back(pair<string,byte>("---",UNIQUE_SS));
     638              : 
     639              :         //      if PrintSurface and a surface level: add more output
     640            0 :                 if(bPrintSurface && gl.is_surface()){
     641            0 :                         vInSS.push_back(pair<string,byte>("all",ALL_SS));
     642            0 :                         vInSS.push_back(pair<string,byte>("pure",SurfaceView::MG_SURFACE_PURE));
     643            0 :                         vInSS.push_back(pair<string,byte>("shadowing",SurfaceView::MG_SURFACE_RIM));
     644            0 :                         vInSS.push_back(pair<string,byte>("shadow-cpy",SurfaceView::MG_SHADOW_RIM_COPY));
     645            0 :                         vInSS.push_back(pair<string,byte>("shadow-nocpy",SurfaceView::MG_SHADOW_RIM_NONCOPY));
     646              :                 }
     647              : 
     648            0 :                 UG_LOG(sLeft<<setw(LEVEL) << left << ssGL.str() << right);
     649            0 :                 stringstream ss; ss << sLeft<<setw(LEVEL)<<"";
     650              :                 string LvlBegin(ss.str());
     651              : 
     652              :         //      Loop Comps
     653            0 :                 for(size_t cmp = 0; cmp < vCmp.size(); ++cmp){
     654              : 
     655              :                         string LineBegin(LvlBegin);
     656              : 
     657              :                 //      write component at first appearance
     658            0 :                         const int fct = vCmp[cmp].second;
     659            0 :                         if(bPrintCmps) {
     660            0 :                                 if(cmp > 0) UG_LOG(LvlBegin);
     661            0 :                                 UG_LOG(sSep<<setw(COMPONENT) << left << vCmp[cmp].first << right);
     662            0 :                                 stringstream ss; ss <<sSep << setw(COMPONENT)<<"";
     663            0 :                                 LineBegin.append(ss.str());
     664            0 :                         }
     665              : 
     666              :                         bool bPrintBegin = false;
     667              : 
     668              :                 //      print interface numbers
     669            0 :                         for(size_t is = 0; is < vInIS.size(); ++is){
     670            0 :                                 for(size_t ss = 0; ss < vInSS.size(); ++ss){
     671            0 :                                         if(bPrintBegin) {UG_LOG(LineBegin);} else bPrintBegin = true;
     672            0 :                                         if(bPrintInterface) UG_LOG(sSep << setw(INTERFACE) << vInIS[is].first);
     673            0 :                                         if(bPrintSurface) UG_LOG(sSep << setw(SURFACE) << vInSS[ss].first);
     674            0 :                                         for(size_t si = 0; si < vSubset.size(); ++si)
     675            0 :                                                 UG_LOG(sSep << setw(NUMBER) << ConvertNumber(dc.num(fct,vSubset[si],vInSS[ss].second,vInIS[is].second),NUMBER,4));
     676            0 :                                         UG_LOG(sRight << endl);
     677              :                                 }
     678              :                         }
     679              : 
     680            0 :                         for(size_t is = 0; is < vContainsIS.size(); ++is){
     681            0 :                                 for(size_t ss = 0; ss < vInSS.size(); ++ss){
     682            0 :                                         if(bPrintBegin) {UG_LOG(LineBegin);} else bPrintBegin = true;
     683            0 :                                         if(bPrintInterface) UG_LOG(sSep << setw(INTERFACE) << vContainsIS[is].first);
     684            0 :                                         if(bPrintSurface) UG_LOG(sSep << setw(SURFACE) << vInSS[ss].first);
     685            0 :                                         for(size_t si = 0; si < vSubset.size(); ++si)
     686            0 :                                                 UG_LOG(sSep << setw(NUMBER) << ConvertNumber(dc.num_contains(fct,vSubset[si],vInSS[ss].second,vContainsIS[is].second),NUMBER,4));
     687            0 :                                         UG_LOG(sRight << endl);
     688              :                                 }
     689              :                         }
     690              :                 }
     691            0 :         }
     692              : 
     693            0 :         UG_LOG(sLeft << repeat('-', LINE) << sRight << endl);
     694              : 
     695              :         UG_LOG(left);
     696            0 :         if(sflags.find("legend") != string::npos){
     697            0 :                 UG_LOG(sLeft<<setw(LINE)<<" GridLevel: underlying grid part"<<sRight<<endl);
     698            0 :                 UG_LOG(sLeft<<setw(LINE)<<"            lev  = level view (all elems in a grid level)"<<sRight<<endl);
     699            0 :                 UG_LOG(sLeft<<setw(LINE)<<"            surf = surface view of a level"<<sRight<<endl);
     700            0 :                 UG_LOG(sLeft<<setw(LINE)<<"                 = all elems in level + elems without child in lower levels"<<sRight<<endl);
     701            0 :                 UG_LOG(sLeft<<setw(LINE)<<"            top  = top surface (leaf elems)"<<sRight<<endl);
     702            0 :                 UG_LOG(sLeft<<setw(LINE)<<"            g    = with ghost elems"<<sRight<<endl);
     703              : 
     704            0 :                 if(bPrintCmps){
     705            0 :                         UG_LOG(sLeft<<setw(LINE)<<" Comps: DoFs in single components"<<sRight<<endl);
     706              :                 }
     707              : 
     708            0 :                 if(bPrintInterface){
     709            0 :                         UG_LOG(sLeft<<setw(LINE)<<" Parallel:  DoFs in parallel interfaces"<<sRight<<endl);
     710            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            (x) = DoFs exactly matching parallel state"<<sRight<<endl);
     711            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            (&) = DoFs containing parallel state"<<sRight<<endl);
     712            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            m = (horiz.) master, s = (horiz.) slave"<<sRight<<endl);
     713            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            vm = vert. master, vs = vert. slave"<<sRight<<endl);
     714            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            no = not contained in interface"<<sRight<<endl);
     715            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            all = all DoFs"<<sRight<<endl);
     716            0 :                         UG_LOG(sLeft<<setw(LINE)<<"            unique = neglecting DoF copies (as if serial run)"<<sRight<<endl);
     717            0 :                         UG_LOG(sLeft<<setw(LINE)<<"                   = no + m (&) + vs (x)"<<sRight<<endl);
     718              :                 }
     719              : 
     720            0 :                 if(bPrintSurface){
     721            0 :                         UG_LOG(sLeft<<setw(LINE)<<" Surface:  DoFs in surface states (matching state exactly)"<<sRight<<endl);
     722            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           pure = inner surface DoF"<<sRight<<endl);
     723            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           shadowing = Shadowing"<<sRight<<endl);
     724            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           shadow-cpy = Shadow Copy (i.e. has same type shadowing)"<<sRight<<endl);
     725            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           shadow-nocpy = Shadow Non-Copy (i.e. has not same type shadowing)"<<sRight<<endl);
     726            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           all = all DoFs"<<sRight<<endl);
     727            0 :                         UG_LOG(sLeft<<setw(LINE)<<"           unique = number of uniquely numbered DoFs"<<sRight<<endl);
     728            0 :                         UG_LOG(sLeft<<setw(LINE)<<"                  = pure + shadowing + shadow-nocpy"<<sRight<<endl);
     729              :                 }
     730              : 
     731            0 :                 UG_LOG(sLeft<<setw(LINE)<<" Domain: DoFs on whole domain"<<sRight<<endl);
     732            0 :                 if(bPrintSubset){
     733            0 :                         UG_LOG(sLeft<<setw(LINE)<<" Subset: DoFs on subset only"<<sRight<<endl);
     734              :                 }
     735              : 
     736            0 :                 UG_LOG(sLeft<<setw(LINE)<<""<<sRight<<endl);
     737            0 :                 UG_LOG(sLeft<<setw(LINE)<<" Call options: print_statistic(\"opt1, opt2, ...\")"<<sRight<<endl);
     738            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   proc:      show DoFs for single proc"<<sRight<<endl);
     739            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   subset:    show DoFs per subset"<<sRight<<endl);
     740            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   interface: show DoFs per parallel interface"<<sRight<<endl);
     741            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   surface:   show DoFs per surface state"<<sRight<<endl);
     742            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   component: show DoFs per component"<<sRight<<endl);
     743            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   legend:    show this legend"<<sRight<<endl);
     744            0 :                 UG_LOG(sLeft<<setw(LINE)<<"   all:       enable all options"<<sRight<<endl);
     745              :         } else {
     746            0 :                 UG_LOG(sLeft << setw(LINE) << "For Legend and Options: print_statistic(\"legend\")."<< sRight << endl);
     747              :         }
     748              :         UG_LOG(right);
     749              : 
     750            0 :         UG_LOG(sLeft << repeat('-', LINE) << sRight << endl);
     751            0 : }
     752              : 
     753            0 : void IApproximationSpace::print_statistic() const
     754              : {
     755            0 :         print_statistic("subset");
     756            0 : }
     757              : 
     758            0 : void IApproximationSpace::print_statistic(std::string flags) const
     759              : {
     760              :         PROFILE_FUNC();
     761              : 
     762              : //      if nothing printed
     763            0 :         if(m_vDD.empty()){
     764              :                 static const char* sLeft = " | ";
     765              :                 static const char* sRight = " | ";
     766              :                 const int LINE = 60;
     767            0 :                 UG_LOG(" --" << repeat('-', LINE) << "-- " << endl);
     768              :                 UG_LOG(left);
     769            0 :                 UG_LOG(sLeft << setw(LINE) << "No DoFDistributions created."<<sRight<<endl);
     770            0 :                 UG_LOG(sLeft << setw(LINE) << "NOTE: DoFDistributions are created only on request."<<sRight<<endl);
     771            0 :                 UG_LOG(sLeft << setw(LINE) << "      However, you may force creation using:"<<sRight<<endl);
     772            0 :                 UG_LOG(sLeft << setw(LINE) << "       - ApproximationSpace::init_levels()"<<sRight<<endl);
     773            0 :                 UG_LOG(sLeft << setw(LINE) << "       - ApproximationSpace::init_surfaces()"<<sRight<<endl);
     774            0 :                 UG_LOG(sLeft << setw(LINE) << "       - ApproximationSpace::init_top_surface()"<<sRight<<endl);
     775              :                 UG_LOG(right);
     776            0 :                 UG_LOG(" --" << repeat('-', LINE) << "-- " << endl);
     777            0 :                 return;
     778              :         }
     779              : 
     780              : //      Get DoF Counts
     781              :         PROFILE_BEGIN(CountLocalDoFStatistic);
     782            0 :         vector<DoFCount> vDC(m_vDD.size());
     783            0 :         for(size_t i = 0; i < vDC.size(); ++i)
     784            0 :                 vDC[i] = m_vDD[i]->dof_count();
     785              :         PROFILE_END();
     786              : 
     787            0 :         string sflags = ToLower(flags);
     788            0 :         if(sflags.find("all") != string::npos)
     789            0 :                 sflags = string("proc, subset, interface, surface, component, legend");
     790              : 
     791            0 :         stringstream ssDDOneProc; ssDDOneProc<<" Number of DoFs";
     792              :         int numProcs = 1;
     793              : #ifdef UG_PARALLEL
     794              :         numProcs = pcl::NumProcs();
     795              :         ssDDOneProc<<" (Proc: "<<pcl::ProcRank()<<" of "<< pcl::NumProcs()<<")";
     796              : #endif
     797              : 
     798              :         bool bPrintOneProc = false;
     799              :         if(sflags.find("proc") != string::npos) bPrintOneProc = true;
     800              :         if(numProcs == 1) bPrintOneProc = false;
     801              : 
     802              : //      Algebra Info
     803              :         const int blockSize = DefaultAlgebra::get().blocksize();
     804            0 :         stringstream ssAlgebra; ssAlgebra << " Algebra: ";
     805            0 :         if(blockSize != AlgebraType::VariableBlockSize)
     806            0 :                 ssAlgebra<<"Block "<<blockSize<<" (divide by "<<blockSize<<" for #Index)";
     807            0 :         else ssAlgebra <<"Flex";
     808              : 
     809              : //      Print infos
     810              :         PROFILE_BEGIN(PrintLocalDoFStatistic);
     811              :         if(bPrintOneProc)
     812              :                 PrintDoFCount(vDC, ssDDOneProc.str(), ssAlgebra.str(), sflags);
     813              :         PROFILE_END();
     814              : 
     815              :         PROFILE_BEGIN(CountGlobalDoFStatistic);
     816            0 :         for(size_t i = 0; i < vDC.size(); ++i)
     817            0 :                 vDC[i].sum_values_over_procs(ug::GetLogAssistant().get_output_process());
     818              :         PROFILE_END();
     819              : 
     820              :         PROFILE_BEGIN(PrintGlobalDoFStatistic);
     821            0 :         PrintDoFCount(vDC, " Number of DoFs (All Procs)", ssAlgebra.str(), sflags);
     822              :         PROFILE_END();
     823            0 : }
     824              : 
     825              : 
     826              : #ifdef UG_PARALLEL
     827              : static size_t NumIndices(const IndexLayout& Layout)
     828              : {
     829              :         size_t sum = 0;
     830              :         for(IndexLayout::const_iterator iter = Layout.begin();
     831              :                         iter != Layout.end(); ++iter)
     832              :                 sum += Layout.interface(iter).size();
     833              :         return sum;
     834              : }
     835              : #endif
     836              : 
     837            0 : void IApproximationSpace::print_layout_statistic() const
     838              : {
     839              : #ifdef UG_PARALLEL
     840              :         static const int LEVEL = 14;
     841              :         static const int NUMBER = 12;
     842              :         static const int SEP = 3;
     843              :         static const int LINE = LEVEL + 4*NUMBER + 4*SEP;
     844              :         static const char* sSep = " | ";
     845              : 
     846              : //      Write header line
     847              :         UG_LOG(" --" << repeat('-', LINE) << "-- " << endl);
     848              :         stringstream ss; ss << " Index Layouts on Proc " <<
     849              :         GetLogAssistant().get_output_process() << " of "<< pcl::NumProcs()
     850              :         << " Procs: " << repeat(' ', 15);
     851              :         UG_LOG(sSep << setw(LINE)<<ss.str() << sSep << endl);
     852              : 
     853              :         UG_LOG(sSep << setw(LEVEL) << "GridLevel  " << sSep);
     854              :         UG_LOG(setw(NUMBER) << "Master  " << sSep);
     855              :         UG_LOG(setw(NUMBER) << "Slave  " << sSep);
     856              :         UG_LOG(setw(NUMBER) << "vert. Master" << sSep);
     857              :         UG_LOG(setw(NUMBER) << "vert. Slave" << sSep << endl);
     858              :         UG_LOG(" |-" << repeat('-', LINE) << "-| " << endl);
     859              : 
     860              : //      Write Infos for Levels
     861              :         for(size_t i = 0; i < m_vDD.size(); ++i){
     862              :                 stringstream ss; ss << m_vDD[i]->grid_level();
     863              :                 UG_LOG(sSep << setw(LEVEL) << left << ss.str() << right << sSep);
     864              :                 UG_LOG(setw(NUMBER) << NumIndices(m_vDD[i]->layouts()->master()) << sSep);
     865              :                 UG_LOG(setw(NUMBER) << NumIndices(m_vDD[i]->layouts()->slave()) << sSep);
     866              :                 UG_LOG(setw(NUMBER) << NumIndices(m_vDD[i]->layouts()->vertical_master()) << sSep);
     867              :                 UG_LOG(setw(NUMBER) << NumIndices(m_vDD[i]->layouts()->vertical_slave()) << sSep << endl);
     868              :         }
     869              :         UG_LOG(" --" << repeat('-', LINE) << "-- " << endl);
     870              : 
     871              : #else
     872              :         UG_LOG(" No Layouts in sequential code.\n");
     873              : #endif
     874            0 : }
     875              : 
     876              : ////////////////////////////////////////////////////////////////////////////////
     877              : // ApproximationSpace
     878              : ////////////////////////////////////////////////////////////////////////////////
     879              : 
     880              : template <typename TDomain>
     881            0 : ApproximationSpace<TDomain>::
     882              : ApproximationSpace(SmartPtr<domain_type> domain)
     883              :         : IApproximationSpace(domain->subset_handler(), domain->grid()),
     884            0 :           m_spDomain(domain)
     885              : {
     886            0 :         if(!m_spDomain.valid())
     887            0 :                 UG_THROW("Domain, passed to ApproximationSpace, is invalid.");
     888            0 :         if(!m_spMGSH.valid())
     889            0 :                 UG_THROW("SubsetHandler, passed to ApproximationSpace, is invalid.");
     890            0 : };
     891              : 
     892              : template <typename TDomain>
     893            0 : ApproximationSpace<TDomain>::
     894              : ApproximationSpace(SmartPtr<domain_type> domain, const AlgebraType& algebraType)
     895              :         : IApproximationSpace(domain->subset_handler(), domain->grid(), algebraType),
     896            0 :           m_spDomain(domain)
     897              : {
     898            0 :         if(!m_spDomain.valid())
     899            0 :                 UG_THROW("Domain, passed to ApproximationSpace, is invalid.");
     900            0 :         if(!m_spMGSH.valid())
     901            0 :                 UG_THROW("SubsetHandler, passed to ApproximationSpace, is invalid.");
     902            0 : };
     903              : 
     904              : } // end namespace ug
     905              : 
     906              : #ifdef UG_DIM_1
     907              : template class ug::ApproximationSpace<ug::Domain1d>;
     908              : #endif
     909              : #ifdef UG_DIM_2
     910              : template class ug::ApproximationSpace<ug::Domain2d>;
     911              : #endif
     912              : #ifdef UG_DIM_3
     913              : template class ug::ApproximationSpace<ug::Domain3d>;
     914              : #endif
        

Generated by: LCOV version 2.0-1