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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-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__DOMAIN_DISC_IMPL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__DOMAIN_DISC_IMPL__
      35              : 
      36              : #include "common/profiler/profiler.h"
      37              : #include "domain_disc.h"
      38              : #include "lib_disc/common/groups_util.h"
      39              : #include "lib_disc/function_spaces/error_indicator_util.h"
      40              : #include "lib_disc/spatial_disc/subset_assemble_util.h"
      41              : #ifdef UG_PARALLEL
      42              : #include "lib_disc/parallelization/parallelization_util.h"
      43              : #endif
      44              : #include "lib_grid/algorithms/debug_util.h"
      45              : 
      46              : namespace ug{
      47              : 
      48              : template <class TElemDisc>
      49              : static void prep_assemble_loop(std::vector<TElemDisc*> vElemDisc)
      50              : {
      51            0 :         for(size_t i = 0; i < vElemDisc.size(); ++i)
      52              :         {
      53            0 :                 vElemDisc[i]->prep_assemble_loop();
      54              :         }
      55              : }
      56              : 
      57              : template <class TElemDisc>
      58              : static void post_assemble_loop(std::vector<TElemDisc*> vElemDisc)
      59              : {
      60            0 :         for(size_t i = 0; i < vElemDisc.size(); ++i)
      61              :         {
      62            0 :                 vElemDisc[i]->post_assemble_loop();
      63              :         }
      64              : }
      65              : 
      66              : 
      67              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
      68            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::update_elem_discs()
      69              : {
      70              : //      check Approximation space
      71            0 :         if(!m_spApproxSpace.valid())
      72            0 :                 UG_THROW("DomainDiscretization: Before using the "
      73              :                                 "DomainDiscretization an ApproximationSpace must be set to it. "
      74              :                                 "Please use DomainDiscretization:set_approximation_space to "
      75              :                                 "set an appropriate Space.");
      76              : 
      77              : //      set approximation space and extract IElemDiscs
      78              :         m_vElemDisc.clear();
      79            0 :         for(size_t i = 0; i < m_vDomainElemDisc.size(); ++i)
      80              :         {
      81            0 :                 m_vDomainElemDisc[i]->set_approximation_space(m_spApproxSpace);
      82              : 
      83            0 :                 if(!(m_spAssTuner->elem_disc_type_enabled(m_vDomainElemDisc[i]->type()))) continue;
      84            0 :                 m_vElemDisc.push_back(m_vDomainElemDisc[i].get());
      85              :         }
      86            0 : }
      87              : 
      88              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
      89            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::update_elem_errors()
      90              : {
      91              : //      check Approximation space
      92            0 :         if(!m_spApproxSpace.valid())
      93            0 :                 UG_THROW("DomainDiscretization: Before using the "
      94              :                                 "DomainDiscretization an ApproximationSpace must be set to it. "
      95              :                                 "Please use DomainDiscretization:set_approximation_space to "
      96              :                                 "set an appropriate Space.");
      97              : 
      98              : //      set approximation space and extract IElemDiscs
      99              :         m_vElemError.clear();
     100            0 :         for(size_t i = 0; i < m_vDomainElemError.size(); ++i)
     101              :         {
     102            0 :                 m_vDomainElemError[i]->set_approximation_space(m_spApproxSpace);
     103              : 
     104            0 :                 if(!(m_spAssTuner->elem_disc_type_enabled(m_vDomainElemError[i]->type()))) continue;
     105            0 :                 m_vElemError.push_back(m_vDomainElemError[i].get());
     106              :         }
     107              : 
     108            0 : }
     109              : 
     110              : 
     111              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     112            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::update_constraints()
     113              : {
     114              : //      check Approximation space
     115            0 :         if(!m_spApproxSpace.valid())
     116            0 :                 UG_THROW("DomainDiscretization: Before using the "
     117              :                                 "DomainDiscretization an ApproximationSpace must be set to it. "
     118              :                                 "Please use DomainDiscretization:set_approximation_space to "
     119              :                                 "set an appropriate Space.");
     120              : 
     121              : 
     122            0 :         for(size_t i = 0; i < m_vConstraint.size(); ++i)
     123            0 :                 m_vConstraint[i]->set_approximation_space(m_spApproxSpace);
     124            0 : }
     125              : 
     126              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     127              : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::update_disc_items()
     128              : {
     129            0 :         update_elem_discs();
     130            0 :         update_constraints();
     131            0 : }
     132              : 
     133              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     134              : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::update_error_items()
     135              : {
     136            0 :         update_elem_errors();
     137            0 :         update_constraints();
     138            0 : }
     139              : 
     140              : ///////////////////////////////////////////////////////////////////////////////
     141              : // Mass Matrix
     142              : ///////////////////////////////////////////////////////////////////////////////
     143              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     144            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     145              : assemble_mass_matrix(matrix_type& M, const vector_type& u,
     146              :                      ConstSmartPtr<DoFDistribution> dd)
     147              : {
     148              :         PROFILE_FUNC_GROUP("discretization");
     149              : //      update the elem discs
     150              :         update_disc_items();
     151            0 :         prep_assemble_loop(m_vElemDisc);
     152              : 
     153              : //      reset matrix to zero and resize
     154            0 :         m_spAssTuner->resize(dd, M);
     155              : 
     156              : //      Union of Subsets
     157            0 :         SubsetGroup unionSubsets;
     158              :         std::vector<SubsetGroup> vSSGrp;
     159              : 
     160              : //      create list of all subsets
     161              :         try{
     162            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
     163            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
     164              : 
     165              : //      loop subsets
     166            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
     167              :         {
     168              :         //      get subset
     169              :                 const int si = unionSubsets[i];
     170              : 
     171              :         //      get dimension of the subset
     172            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
     173              : 
     174              :         //      request if subset is regular grid
     175            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
     176              : 
     177              :         //      overrule by regular grid if required
     178            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
     179              : 
     180              :         //      Elem Disc on the subset
     181              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
     182              : 
     183              :         //      get all element discretizations that work on the subset
     184            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
     185              : 
     186              :         //      assemble on suitable elements
     187              :                 try
     188              :                 {
     189            0 :                 switch(dim)
     190              :                 {
     191            0 :                 case 0:
     192              :                         this->template AssembleMassMatrix<RegularVertex>
     193            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     194            0 :                         break;
     195            0 :                 case 1:
     196              :                         this->template AssembleMassMatrix<RegularEdge>
     197            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     198              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     199              :                         this->template AssembleMassMatrix<ConstrainingEdge>
     200            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     201            0 :                         break;
     202            0 :                 case 2:
     203              :                         this->template AssembleMassMatrix<Triangle>
     204            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     205              :                         this->template AssembleMassMatrix<Quadrilateral>
     206            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     207              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     208              :                         this->template AssembleMassMatrix<ConstrainingTriangle>
     209            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     210              :                         this->template AssembleMassMatrix<ConstrainingQuadrilateral>
     211            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     212            0 :                         break;
     213            0 :                 case 3:
     214              :                         this->template AssembleMassMatrix<Tetrahedron>
     215            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     216              :                         this->template AssembleMassMatrix<Pyramid>
     217            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     218              :                         this->template AssembleMassMatrix<Prism>
     219            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     220              :                         this->template AssembleMassMatrix<Hexahedron>
     221            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     222              :                         this->template AssembleMassMatrix<Octahedron>
     223            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, M, u);
     224            0 :                         break;
     225            0 :                 default:
     226            0 :                         UG_THROW("DomainDiscretization::assemble_mass_matrix:"
     227              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
     228              :                 }
     229              :                 }
     230            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_mass_matrix:"
     231              :                                                 " Assembling of elements of Dimension " << dim << " in "
     232              :                                                 " subset "<<si<< " failed.");
     233              :         }
     234              : 
     235              : //      post process
     236              :         try{
     237            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
     238            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     239            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
     240            0 :                         if(m_vConstraint[i]->type() & type)
     241              :                         {
     242            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     243            0 :                                 m_vConstraint[i]->adjust_jacobian(M, u, dd, type);
     244              :                         }
     245              :         }
     246            0 :         post_assemble_loop(m_vElemDisc);
     247            0 :         }UG_CATCH_THROW("DomainDiscretization::assemble_mass_matrix:"
     248              :                                         " Cannot execute post process.");
     249              : 
     250              : //      Remember parallel storage type
     251              : #ifdef UG_PARALLEL
     252              :         M.set_storage_type(PST_ADDITIVE);
     253              :         M.set_layouts(dd->layouts());
     254              : #endif
     255            0 : }
     256              : 
     257              : /**
     258              :  * This function adds the contributions of all passed element discretizations
     259              :  * on one given subset to the global Mass matrix.
     260              :  *
     261              :  * \param[in]           vElemDisc               element discretizations
     262              :  * \param[in]           dd                              DoF Distribution
     263              :  * \param[in]           si                              subset index
     264              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     265              :  * \param[in,out]       M                               Mass matrix
     266              :  * \param[in]           u                               solution
     267              :  */
     268              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     269              : template <typename TElem>
     270            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     271              : AssembleMassMatrix( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     272              :                                         ConstSmartPtr<DoFDistribution> dd,
     273              :                                         int si, bool bNonRegularGrid,
     274              :                                         matrix_type& M,
     275              :                                         const vector_type& u)
     276              : {
     277              :         //      check if only some elements are selected
     278            0 :         if(m_spAssTuner->selected_elements_used())
     279              :         {
     280              :                 std::vector<TElem*> vElem;
     281            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
     282              : 
     283              :                 //      assembling is carried out only over those elements
     284              :                 //      which are selected and in subset si
     285              :                 gass_type::template AssembleMassMatrix<TElem>
     286            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
     287              :                          bNonRegularGrid, M, u, m_spAssTuner);
     288            0 :         }
     289              :         else
     290              :         {
     291              :                 //      general case: assembling over all elements in subset si
     292              :                 gass_type::template AssembleMassMatrix<TElem>
     293            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
     294              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
     295              :                                         bNonRegularGrid, M, u, m_spAssTuner);
     296              :         }
     297            0 : }
     298              : 
     299              : ///////////////////////////////////////////////////////////////////////////////
     300              : // Stiffness Matrix
     301              : ///////////////////////////////////////////////////////////////////////////////
     302              : 
     303              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     304            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     305              : assemble_stiffness_matrix(matrix_type& A, const vector_type& u,
     306              :                           ConstSmartPtr<DoFDistribution> dd)
     307              : {
     308              :         PROFILE_FUNC_GROUP("discretization");
     309              : //      update the elem discs
     310              :         update_disc_items();
     311            0 :         prep_assemble_loop(m_vElemDisc);
     312              : 
     313              : //      reset matrix to zero and resize
     314            0 :         m_spAssTuner->resize(dd, A);
     315              : 
     316              : //      Union of Subsets
     317            0 :         SubsetGroup unionSubsets;
     318              :         std::vector<SubsetGroup> vSSGrp;
     319              : 
     320              : //      create list of all subsets
     321              :         try{
     322            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
     323            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
     324              : 
     325              : //      loop subsets
     326            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
     327              :         {
     328              :         //      get subset
     329              :                 const int si = unionSubsets[i];
     330              : 
     331              :         //      get dimension of the subset
     332            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
     333              : 
     334              :         //      request if subset is regular grid
     335            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
     336              : 
     337              :         //      overrule by regular grid if required
     338            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
     339              : 
     340              :         //      Elem Disc on the subset
     341              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
     342              : 
     343              :         //      get all element discretizations that work on the subset
     344            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
     345              : 
     346              :         //      assemble on suitable elements
     347              :                 try
     348              :                 {
     349            0 :                 switch(dim)
     350              :                 {
     351            0 :                 case 0:
     352              :                         this->template AssembleStiffnessMatrix<RegularVertex>
     353            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     354            0 :                         break;
     355            0 :                 case 1:
     356              :                         this->template AssembleStiffnessMatrix<RegularEdge>
     357            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     358              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     359              :                         this->template AssembleStiffnessMatrix<ConstrainingEdge>
     360            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     361            0 :                         break;
     362            0 :                 case 2:
     363              :                         this->template AssembleStiffnessMatrix<Triangle>
     364            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     365              :                         this->template AssembleStiffnessMatrix<Quadrilateral>
     366            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     367              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     368              :                         this->template AssembleStiffnessMatrix<ConstrainingTriangle>
     369            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     370              :                         this->template AssembleStiffnessMatrix<ConstrainingQuadrilateral>
     371            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     372            0 :                         break;
     373            0 :                 case 3:
     374              :                         this->template AssembleStiffnessMatrix<Tetrahedron>
     375            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     376              :                         this->template AssembleStiffnessMatrix<Pyramid>
     377            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     378              :                         this->template AssembleStiffnessMatrix<Prism>
     379            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     380              :                         this->template AssembleStiffnessMatrix<Hexahedron>
     381            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     382              :                         this->template AssembleStiffnessMatrix<Octahedron>
     383            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, A, u);
     384            0 :                         break;
     385            0 :                 default:
     386            0 :                         UG_THROW("DomainDiscretization::assemble_stiffness_matrix:"
     387              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
     388              :                 }
     389              :                 }
     390            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_stiffness_matrix:"
     391              :                                         " Assembling of elements of Dimension " << dim << " in "
     392              :                                         " subset "<<si<< " failed.");
     393              :         }
     394              : 
     395              : //      post process
     396              :         try{
     397            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
     398            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     399            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
     400            0 :                         if(m_vConstraint[i]->type() & type)
     401              :                         {
     402            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     403            0 :                                 m_vConstraint[i]->adjust_jacobian(A, u, dd, type);
     404              :                         }
     405              :         }
     406            0 :         post_assemble_loop(m_vElemDisc);
     407            0 :         }UG_CATCH_THROW("DomainDiscretization::assemble_stiffness_matrix:"
     408              :                                         " Cannot execute post process.");
     409              : 
     410              : //      Remember parallel storage type
     411              : #ifdef UG_PARALLEL
     412              :         A.set_storage_type(PST_ADDITIVE);
     413              :         A.set_layouts(dd->layouts());
     414              : #endif
     415            0 : }
     416              : 
     417              : /**
     418              :  * This function adds the contributions of all passed element discretizations
     419              :  * on one given subset to the global Stiffness matrix.
     420              :  *
     421              :  * \param[in]           vElemDisc               element discretizations
     422              :  * \param[in]           dd                              DoF Distribution
     423              :  * \param[in]           si                              subset index
     424              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     425              :  * \param[in,out]       A                               Stiffness matrix
     426              :  * \param[in]           u                               solution
     427              :  */
     428              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     429              : template <typename TElem>
     430            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     431              : AssembleStiffnessMatrix(        const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     432              :                                                         ConstSmartPtr<DoFDistribution> dd,
     433              :                                                         int si, bool bNonRegularGrid,
     434              :                                                         matrix_type& A,
     435              :                                                         const vector_type& u)
     436              : {
     437              :         //      check if only some elements are selected
     438            0 :         if(m_spAssTuner->selected_elements_used())
     439              :         {
     440              :                 std::vector<TElem*> vElem;
     441            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
     442              : 
     443              :                 //      assembling is carried out only over those elements
     444              :                 //      which are selected and in subset si
     445              :                 gass_type::template AssembleStiffnessMatrix<TElem>
     446            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
     447              :                          bNonRegularGrid, A, u, m_spAssTuner);
     448            0 :         }
     449              :         else
     450              :         {
     451              :                 //      general case: assembling over all elements in subset si
     452              :                 gass_type::template AssembleStiffnessMatrix<TElem>
     453            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
     454              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
     455              :                                         bNonRegularGrid, A, u, m_spAssTuner);
     456              :         }
     457            0 : }
     458              : 
     459              : //////////////////////////////////////////////////////////////////////////////
     460              : //////////////////////////////////////////////////////////////////////////////
     461              : //  Time Independent (stationary)
     462              : //////////////////////////////////////////////////////////////////////////////
     463              : //////////////////////////////////////////////////////////////////////////////
     464              : 
     465              : 
     466              : ///////////////////////////////////////////////////////////////////////////////
     467              : // Jacobian (stationary)
     468              : ///////////////////////////////////////////////////////////////////////////////
     469              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     470            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     471              : assemble_jacobian(matrix_type& J,
     472              :                   const vector_type& u,
     473              :                   ConstSmartPtr<DoFDistribution> dd)
     474              : {
     475              :         PROFILE_FUNC_GROUP("discretization");
     476              : //      update the elem discs
     477              :         update_disc_items();
     478            0 :         prep_assemble_loop(m_vElemDisc);
     479              : 
     480              : //      reset matrix to zero and resize
     481            0 :         m_spAssTuner->resize(dd, J);
     482              : 
     483              : //      Union of Subsets
     484            0 :         SubsetGroup unionSubsets;
     485              :         std::vector<SubsetGroup> vSSGrp;
     486              : 
     487              : //      pre process -  modifies the solution, used for computing the defect
     488              :         const vector_type* pModifyU = &u;
     489              :         SmartPtr<vector_type> pModifyMemory;
     490            0 :         if( m_spAssTuner->modify_solution_enabled() ){
     491            0 :                 pModifyMemory = u.clone();
     492              :                 pModifyU = pModifyMemory.get();
     493              :                 try{
     494            0 :                 for(int type = 1; type < CT_ALL; type = type << 1){
     495            0 :                         if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     496            0 :                         for(size_t i = 0; i < m_vConstraint.size(); ++i)
     497            0 :                                 if(m_vConstraint[i]->type() & type)
     498            0 :                                         m_vConstraint[i]->modify_solution(*pModifyMemory, u, dd, type);
     499              :                 }
     500            0 :                 } UG_CATCH_THROW("Cannot modify solution.");
     501              :         }
     502              : 
     503              : 
     504              : 
     505              : //      create list of all subsets
     506              :         try{
     507            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
     508            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
     509              : 
     510              : //      loop subsets
     511            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
     512              :         {
     513              :         //      get subset
     514              :                 const int si = unionSubsets[i];
     515              : 
     516              :         //      get dimension of the subset
     517            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
     518              : 
     519              :         //      request if subset is regular grid
     520            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
     521              : 
     522              :         //      overrule by regular grid if required
     523            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
     524              : 
     525              :         //      Elem Disc on the subset
     526              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
     527              : 
     528              :         //      get all element discretizations that work on the subset
     529            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
     530              : 
     531              :         //      assemble on suitable elements
     532              :                 try
     533              :                 {
     534            0 :                 switch(dim)
     535              :                 {
     536            0 :                 case 0:
     537              :                         this->template AssembleJacobian<RegularVertex>
     538            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     539            0 :                         break;
     540            0 :                 case 1:
     541              :                         this->template AssembleJacobian<RegularEdge>
     542            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     543              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     544              :                         this->template AssembleJacobian<ConstrainingEdge>
     545            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     546            0 :                         break;
     547            0 :                 case 2:
     548              :                         this->template AssembleJacobian<Triangle>
     549            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     550              :                         this->template AssembleJacobian<Quadrilateral>
     551            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     552              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     553              :                         this->template AssembleJacobian<ConstrainingTriangle>
     554            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     555              :                         this->template AssembleJacobian<ConstrainingQuadrilateral>
     556            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     557            0 :                         break;
     558            0 :                 case 3:
     559              :                         this->template AssembleJacobian<Tetrahedron>
     560            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     561              :                         this->template AssembleJacobian<Pyramid>
     562            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     563              :                         this->template AssembleJacobian<Prism>
     564            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     565              :                         this->template AssembleJacobian<Hexahedron>
     566            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     567              :                         this->template AssembleJacobian<Octahedron>
     568            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, *pModifyU);
     569            0 :                         break;
     570            0 :                 default:
     571            0 :                         UG_THROW("DomainDiscretization::assemble_jacobian (stationary):"
     572              :                                                         "Dimension "<<dim<<"(subset="<<si<<") not supported");
     573              :                 }
     574              :                 }
     575            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_jacobian (stationary):"
     576              :                                                 " Assembling of elements of Dimension " << dim << " in "
     577              :                                                 " subset "<<si<< " failed.");
     578              :         }
     579              : 
     580              : //      post process
     581              :         try{
     582            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
     583            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     584            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
     585            0 :                         if(m_vConstraint[i]->type() & type)
     586              :                         {
     587            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     588            0 :                                 m_vConstraint[i]->adjust_jacobian(J, *pModifyU, dd, type);
     589              :                         }
     590              :         }
     591            0 :         post_assemble_loop(m_vElemDisc);
     592            0 :         }UG_CATCH_THROW("DomainDiscretization::assemble_jacobian:"
     593              :                                         " Cannot execute post process.");
     594              : 
     595              : //      Remember parallel storage type
     596              : #ifdef UG_PARALLEL
     597              :         J.set_storage_type(PST_ADDITIVE);
     598              :         J.set_layouts(dd->layouts());
     599              : #endif
     600            0 : }
     601              : 
     602              : /**
     603              :  * This function adds the contributions of all passed element discretizations
     604              :  * on one given subset to the global Jacobian in the stationary case.
     605              :  *
     606              :  * \param[in]           vElemDisc               element discretizations
     607              :  * \param[in]           si                              subset index
     608              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     609              :  * \param[in,out]       J                               jacobian
     610              :  * \param[in]           u                               solution
     611              :  */
     612              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     613              : template <typename TElem>
     614            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     615              : AssembleJacobian(       const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     616              :                                         ConstSmartPtr<DoFDistribution> dd,
     617              :                                         int si, bool bNonRegularGrid,
     618              :                                         matrix_type& J,
     619              :                                         const vector_type& u)
     620              : {
     621              :         //      check if only some elements are selected
     622            0 :         if(m_spAssTuner->selected_elements_used())
     623              :         {
     624              :                 std::vector<TElem*> vElem;
     625            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
     626              : 
     627              :                 //      assembling is carried out only over those elements
     628              :                 //      which are selected and in subset si
     629              :                 gass_type::template AssembleJacobian<TElem>
     630            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
     631              :                          bNonRegularGrid, J, u, m_spAssTuner);
     632            0 :         }
     633              :         else
     634              :         {
     635              :                 //      general case: assembling over all elements in subset si
     636              :                 gass_type::template AssembleJacobian<TElem>
     637            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
     638              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
     639              :                                         bNonRegularGrid, J, u, m_spAssTuner);
     640              :         }
     641            0 : }
     642              : 
     643              : ///////////////////////////////////////////////////////////////////////////////
     644              : // Defect (stationary)
     645              : ///////////////////////////////////////////////////////////////////////////////
     646              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     647            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     648              : assemble_defect(vector_type& d,
     649              :                 const vector_type& u,
     650              :                 ConstSmartPtr<DoFDistribution> dd)
     651              : {
     652              :         PROFILE_FUNC_GROUP("discretization");
     653              : //      update the elem discs
     654              :         update_disc_items();
     655            0 :         prep_assemble_loop(m_vElemDisc);
     656              : 
     657              : //      reset matrix to zero and resize
     658            0 :         m_spAssTuner->resize(dd, d);
     659              : 
     660              : //      Union of Subsets
     661            0 :         SubsetGroup unionSubsets;
     662              :         std::vector<SubsetGroup> vSSGrp;
     663              : 
     664              : //      pre process -  modifies the solution, used for computing the defect
     665              :         const vector_type* pModifyU = &u;
     666              :         SmartPtr<vector_type> pModifyMemory;
     667            0 :         if( m_spAssTuner->modify_solution_enabled() ){
     668            0 :                 pModifyMemory = u.clone();
     669              :                 pModifyU = pModifyMemory.get();
     670              :                 try{
     671            0 :                 for(int type = 1; type < CT_ALL; type = type << 1){
     672            0 :                         if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     673            0 :                         for(size_t i = 0; i < m_vConstraint.size(); ++i)
     674            0 :                                 if(m_vConstraint[i]->type() & type)
     675            0 :                                         m_vConstraint[i]->modify_solution(*pModifyMemory, u, dd, type);
     676              :                 }
     677            0 :                 } UG_CATCH_THROW("Cannot modify solution.");
     678              :         }
     679              : 
     680              : //      create list of all subsets
     681              :         try{
     682            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
     683            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
     684              : 
     685              : //      loop subsets
     686            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
     687              :         {
     688              :         //      get subset
     689              :                 const int si = unionSubsets[i];
     690              : 
     691              :         //      get dimension of the subset
     692            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
     693              : 
     694              :         //      request if subset is regular grid
     695            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
     696              : 
     697              :         //      overrule by regular grid if required
     698            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
     699              : 
     700              :         //      Elem Disc on the subset
     701              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
     702              : 
     703              :         //      get all element discretizations that work on the subset
     704            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
     705              : 
     706              :         //      assemble on suitable elements
     707              :                 try
     708              :                 {
     709            0 :                 switch(dim)
     710              :                 {
     711            0 :                 case 0:
     712              :                         this->template AssembleDefect<RegularVertex>
     713            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     714            0 :                         break;
     715            0 :                 case 1:
     716              :                         this->template AssembleDefect<RegularEdge>
     717            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     718              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     719              :                         this->template AssembleDefect<ConstrainingEdge>
     720            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     721            0 :                         break;
     722            0 :                 case 2:
     723              :                         this->template AssembleDefect<Triangle>
     724            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     725              :                         this->template AssembleDefect<Quadrilateral>
     726            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     727              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     728              :                         this->template AssembleDefect<ConstrainingTriangle>
     729            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     730              :                         this->template AssembleDefect<ConstrainingQuadrilateral>
     731            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     732            0 :                         break;
     733            0 :                 case 3:
     734              :                         this->template AssembleDefect<Tetrahedron>
     735            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     736              :                         this->template AssembleDefect<Pyramid>
     737            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     738              :                         this->template AssembleDefect<Prism>
     739            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     740              :                         this->template AssembleDefect<Hexahedron>
     741            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     742              :                         this->template AssembleDefect<Octahedron>
     743            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, *pModifyU);
     744            0 :                         break;
     745            0 :                 default:
     746            0 :                         UG_THROW("DomainDiscretization::assemble_defect (stationary):"
     747              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
     748              :                 }
     749              :                 }
     750            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_defect (stationary):"
     751              :                                                 " Assembling of elements of Dimension " << dim << " in "
     752              :                                                 " subset "<<si<< " failed.");
     753              :         }
     754              : 
     755              : //      post process
     756              :         try{
     757              : 
     758              :         // Dirichlet first, since hanging nodes might be constrained by Dirichlet nodes
     759            0 :         if (m_spAssTuner->constraint_type_enabled(CT_DIRICHLET))
     760              :         {
     761            0 :                 for (size_t i = 0; i < m_vConstraint.size(); ++i)
     762              :                 {
     763            0 :                         if (m_vConstraint[i]->type() & CT_DIRICHLET)
     764              :                         {
     765            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     766            0 :                                 m_vConstraint[i]->adjust_defect(d, *pModifyU, dd, CT_DIRICHLET);
     767              :                         }
     768              :                 }
     769              :         }
     770              : 
     771            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
     772            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     773            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
     774            0 :                         if(m_vConstraint[i]->type() & type)
     775              :                         {
     776            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     777            0 :                                 m_vConstraint[i]->adjust_defect(d, *pModifyU, dd, type);
     778              :                         }
     779              :         }
     780            0 :         post_assemble_loop(m_vElemDisc);
     781            0 :         } UG_CATCH_THROW("Cannot adjust defect.");
     782              : 
     783              : 
     784              : //      Remember parallel storage type
     785              : #ifdef UG_PARALLEL
     786              :         d.set_storage_type(PST_ADDITIVE);
     787              : #endif
     788            0 : }
     789              : 
     790              : /**
     791              :  * This function adds the contributions of all passed element discretizations
     792              :  * on one given subset to the global Defect in the stationary case.
     793              :  *
     794              :  * \param[in]           vElemDisc               element discretizations
     795              :  * \param[in]           dd                              DoF Distribution
     796              :  * \param[in]           si                              subset index
     797              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     798              :  * \param[in,out]       d                               defect
     799              :  * \param[in]           u                               solution
     800              :  */
     801              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     802              : template <typename TElem>
     803            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     804              : AssembleDefect( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     805              :                                 ConstSmartPtr<DoFDistribution> dd,
     806              :                                 int si, bool bNonRegularGrid,
     807              :                                 vector_type& d,
     808              :                                 const vector_type& u)
     809              : {
     810              :         //      check if only some elements are selected
     811            0 :         if(m_spAssTuner->selected_elements_used())
     812              :         {
     813              :                 std::vector<TElem*> vElem;
     814            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
     815              : 
     816              :                 //      assembling is carried out only over those elements
     817              :                 //      which are selected and in subset si
     818              :                 gass_type::template AssembleDefect<TElem>
     819            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
     820              :                          bNonRegularGrid, d, u, m_spAssTuner);
     821            0 :         }
     822              :         else
     823              :         {
     824              :                 //      general case: assembling over all elements in subset si
     825              :                 gass_type::template AssembleDefect<TElem>
     826            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
     827              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
     828              :                                         bNonRegularGrid, d, u, m_spAssTuner);
     829              :         }
     830            0 : }
     831              : 
     832              : ///////////////////////////////////////////////////////////////////////////////
     833              : // Matrix and RHS (stationary)
     834              : ///////////////////////////////////////////////////////////////////////////////
     835              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     836            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     837              : assemble_linear(matrix_type& mat, vector_type& rhs,
     838              :                 ConstSmartPtr<DoFDistribution> dd)
     839              : {
     840              :         PROFILE_FUNC_GROUP("discretization");
     841              : //      update the elem discs
     842              :         update_disc_items();
     843            0 :         prep_assemble_loop(m_vElemDisc);
     844              : 
     845              : //      reset matrix to zero and resize
     846            0 :         m_spAssTuner->resize(dd, mat);
     847            0 :         m_spAssTuner->resize(dd, rhs);
     848              : 
     849              : //      Union of Subsets
     850            0 :         SubsetGroup unionSubsets;
     851              :         std::vector<SubsetGroup> vSSGrp;
     852              : 
     853              : //      create list of all subsets
     854              :         try{
     855            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
     856            0 :         }UG_CATCH_THROW("DomainDiscretization: Can not create Subset Groups and Union.");
     857              : 
     858              : //      loop subsets
     859            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
     860              :         {
     861              :         //      get subset
     862              :                 const int si = unionSubsets[i];
     863              : 
     864              :         //      get dimension of the subset
     865            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
     866              : 
     867              :         //      request if subset is regular grid
     868            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
     869              : 
     870              :         //      overrule by regular grid if required
     871            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
     872              : 
     873              :         //      Elem Disc on the subset
     874              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
     875              : 
     876              :         //      get all element discretizations that work on the subset
     877            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
     878              : 
     879              :         //      assemble on suitable elements
     880              :                 try
     881              :                 {
     882            0 :                 switch(dim)
     883              :                 {
     884            0 :                 case 0:
     885              :                         this->template AssembleLinear<RegularVertex>
     886            0 :                                         (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     887            0 :                         break;
     888            0 :                 case 1:
     889              :                         this->template AssembleLinear<RegularEdge>
     890            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     891              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     892              :                         this->template AssembleLinear<ConstrainingEdge>
     893            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     894            0 :                         break;
     895            0 :                 case 2:
     896              :                         this->template AssembleLinear<Triangle>
     897            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     898              :                         this->template AssembleLinear<Quadrilateral>
     899            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     900              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
     901              :                         this->template AssembleLinear<ConstrainingTriangle>
     902            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     903              :                         this->template AssembleLinear<ConstrainingQuadrilateral>
     904            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     905            0 :                         break;
     906            0 :                 case 3:
     907              :                         this->template AssembleLinear<Tetrahedron>
     908            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     909              :                         this->template AssembleLinear<Pyramid>
     910            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     911              :                         this->template AssembleLinear<Prism>
     912            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     913              :                         this->template AssembleLinear<Hexahedron>
     914            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     915              :                         this->template AssembleLinear<Octahedron>
     916            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs);
     917            0 :                         break;
     918            0 :                 default:
     919            0 :                         UG_THROW("DomainDiscretization::assemble_linear (stationary):"
     920              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
     921              :                 }
     922              :                 }
     923            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_linear (stationary):"
     924              :                                                 " Assembling of elements of Dimension " << dim << " in "
     925              :                                                 " subset "<<si<< " failed.");
     926              :         }
     927              : 
     928              : //      post process
     929              :         try{
     930            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
     931            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
     932            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
     933            0 :                         if(m_vConstraint[i]->type() & type)
     934              :                         {
     935            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
     936            0 :                                 m_vConstraint[i]->adjust_linear(mat, rhs, dd, type);
     937              :                         }
     938              :         }
     939            0 :         post_assemble_loop(m_vElemDisc);
     940            0 :         }UG_CATCH_THROW("DomainDiscretization::assemble_linear: Cannot post process.");
     941              : 
     942              : //      Remember parallel storage type
     943              : #ifdef UG_PARALLEL
     944              :         mat.set_storage_type(PST_ADDITIVE);
     945              :         mat.set_layouts(dd->layouts());
     946              :         rhs.set_storage_type(PST_ADDITIVE);
     947              : #endif
     948            0 : }
     949              : 
     950              : /**
     951              :  * This function adds the contributions of all passed element discretizations
     952              :  * on one given subset to the global Matrix and the global Right-Hand Side
     953              :  * of the Linear problem in the stationary case.
     954              :  *
     955              :  * \param[in]           vElemDisc               element discretizations
     956              :  * \param[in]           dd                              DoF Distribution
     957              :  * \param[in]           si                              subset index
     958              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     959              :  * \param[in,out]       A                               Matrix
     960              :  * \param[in,out]       rhs                             Right-hand side
     961              :  */
     962              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     963              : template <typename TElem>
     964            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     965              : AssembleLinear( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     966              :                                 ConstSmartPtr<DoFDistribution> dd,
     967              :                                 int si, bool bNonRegularGrid,
     968              :                                 matrix_type& A,
     969              :                                 vector_type& rhs)
     970              : {
     971              :         //      check if only some elements are selected
     972            0 :         if(m_spAssTuner->selected_elements_used())
     973              :         {
     974              :                 std::vector<TElem*> vElem;
     975            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
     976              : 
     977              :                 //      assembling is carried out only over those elements
     978              :                 //      which are selected and in subset si
     979              :                 gass_type::template AssembleLinear<TElem>
     980            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
     981              :                          bNonRegularGrid, A, rhs, m_spAssTuner);
     982            0 :         }
     983              :         else
     984              :         {
     985              :                 //      general case: assembling over all elements in subset si
     986              :                 gass_type::template AssembleLinear<TElem>
     987            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
     988              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
     989              :                                         bNonRegularGrid, A, rhs, m_spAssTuner);
     990              :         }
     991            0 : }
     992              : 
     993              : ///////////////////////////////////////////////////////////////////////////////
     994              : // RHS (stationary)
     995              : ///////////////////////////////////////////////////////////////////////////////
     996              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
     997            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
     998              : assemble_rhs(vector_type& rhs,
     999              :                         const vector_type& u,
    1000              :                         ConstSmartPtr<DoFDistribution> dd)
    1001              : {
    1002              :         PROFILE_FUNC_GROUP("discretization");
    1003              : //      update the elem discs
    1004              :         update_disc_items();
    1005            0 :         prep_assemble_loop(m_vElemDisc);
    1006              : 
    1007              : //      reset matrix to zero and resize
    1008            0 :         m_spAssTuner->resize(dd, rhs);
    1009              : 
    1010              : //      Union of Subsets
    1011            0 :         SubsetGroup unionSubsets;
    1012              :         std::vector<SubsetGroup> vSSGrp;
    1013              : 
    1014              : //      create list of all subsets
    1015              :         try{
    1016            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1017            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1018              : 
    1019              : //      loop subsets
    1020            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1021              :         {
    1022              :         //      get subset
    1023              :                 const int si = unionSubsets[i];
    1024              : 
    1025              :         //      get dimension of the subset
    1026            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1027              : 
    1028              :         //      request if subset is regular grid
    1029            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1030              : 
    1031              :         //      overrule by regular grid if required
    1032            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1033              : 
    1034              :         //      Elem Disc on the subset
    1035              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1036              : 
    1037              :         //      get all element discretizations that work on the subset
    1038            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1039              : 
    1040              :         //      assemble on suitable elements
    1041              :                 try
    1042              :                 {
    1043            0 :                 switch(dim)
    1044              :                 {
    1045            0 :                 case 0:
    1046              :                         this->template AssembleRhs<RegularVertex>
    1047            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1048            0 :                         break;
    1049            0 :                 case 1:
    1050              :                         this->template AssembleRhs<RegularEdge>
    1051            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1052              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1053              :                         this->template AssembleRhs<ConstrainingEdge>
    1054            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1055            0 :                         break;
    1056            0 :                 case 2:
    1057              :                         this->template AssembleRhs<Triangle>
    1058            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1059              :                         this->template AssembleRhs<Quadrilateral>
    1060            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1061              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1062              :                         this->template AssembleRhs<ConstrainingTriangle>
    1063            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1064              :                         this->template AssembleRhs<ConstrainingQuadrilateral>
    1065            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1066            0 :                         break;
    1067            0 :                 case 3:
    1068              :                         this->template AssembleRhs<Tetrahedron>
    1069            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1070              :                         this->template AssembleRhs<Pyramid>
    1071            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1072              :                         this->template AssembleRhs<Prism>
    1073            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1074              :                         this->template AssembleRhs<Hexahedron>
    1075            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1076              :                         this->template AssembleRhs<Octahedron>
    1077            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, u);
    1078            0 :                         break;
    1079            0 :                 default:
    1080            0 :                         UG_THROW("DomainDiscretization::assemble_rhs (stationary):"
    1081              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1082              :                 }
    1083              :                 }
    1084            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_rhs (stationary):"
    1085              :                                                 " Assembling of elements of Dimension " << dim << " in "
    1086              :                                                 " subset "<<si<< " failed.");
    1087              :         }
    1088              : 
    1089              : //      post process
    1090              :         try{
    1091            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
    1092            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1093            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1094            0 :                         if(m_vConstraint[i]->type() & type)
    1095              :                         {
    1096            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    1097            0 :                                 m_vConstraint[i]->adjust_rhs(rhs, u, dd, type);
    1098              :                         }
    1099              :         }
    1100            0 :         post_assemble_loop(m_vElemDisc);
    1101            0 :         }UG_CATCH_THROW("DomainDiscretization::assemble_rhs:"
    1102              :                                         " Cannot execute post process.");
    1103              : 
    1104              : //      Remember parallel storage type
    1105              : #ifdef UG_PARALLEL
    1106              :         rhs.set_storage_type(PST_ADDITIVE);
    1107              : #endif
    1108            0 : }
    1109              : 
    1110              : /**
    1111              :  * This function adds the contributions of all passed element discretizations
    1112              :  * on one given subset to the global Right-Hand Side.
    1113              :  *
    1114              :  * \param[in]           vElemDisc               element discretizations
    1115              :  * \param[in]           dd                              DoF Distribution
    1116              :  * \param[in]           si                              subset index
    1117              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1118              :  * \param[in,out]       rhs                             Right-hand side
    1119              :  * \param[in]           u                               solution
    1120              :  */
    1121              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1122              : template <typename TElem>
    1123            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1124              : AssembleRhs(    const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1125              :                                 ConstSmartPtr<DoFDistribution> dd,
    1126              :                                 int si, bool bNonRegularGrid,
    1127              :                                 vector_type& rhs,
    1128              :                                 const vector_type& u)
    1129              : {
    1130              :         //      check if only some elements are selected
    1131            0 :         if(m_spAssTuner->selected_elements_used())
    1132              :         {
    1133              :                 std::vector<TElem*> vElem;
    1134            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    1135              : 
    1136              :                 //      assembling is carried out only over those elements
    1137              :                 //      which are selected and in subset si
    1138              :                 gass_type::template AssembleRhs<TElem>
    1139            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    1140              :                          bNonRegularGrid, rhs, u, m_spAssTuner);
    1141            0 :         }
    1142              :         else
    1143              :         {
    1144              :                 //      general case: assembling over all elements in subset si
    1145              :                 gass_type::template AssembleRhs<TElem>
    1146            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    1147              :                                         bNonRegularGrid, rhs, u, m_spAssTuner);
    1148              :         }
    1149            0 : }
    1150              : 
    1151              : ///////////////////////////////////////////////////////////////////////////////
    1152              : // set constraints (stationary)
    1153              : ///////////////////////////////////////////////////////////////////////////////
    1154              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1155            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1156              : adjust_solution(vector_type& u, ConstSmartPtr<DoFDistribution> dd)
    1157              : {
    1158              :         PROFILE_FUNC_GROUP("discretization");
    1159            0 :         update_constraints();
    1160              : 
    1161              :         // NOTE: it is crucial, that dirichlet pp are processed before constraints.
    1162              :         //               otherwise we may start with an inconsistent solution in the solvers
    1163            0 :         std::vector<int> vType(6);
    1164            0 :         vType[0] = CT_DIRICHLET;        // hanging (or other constrained) nodes might depend on Dirichlet nodes
    1165            0 :         vType[1] = CT_CONSTRAINTS;
    1166            0 :         vType[2] = CT_HANGING;
    1167            0 :         vType[3] = CT_MAY_DEPEND_ON_HANGING;
    1168            0 :         vType[4] = CT_ASSEMBLED;
    1169            0 :         vType[5] = CT_DIRICHLET;        // hanging DoFs might be Dirichlet (Dirichlet overrides)
    1170              : 
    1171              :         // if assembling is carried out at one DoF only, u needs to be resized
    1172            0 :         if (m_spAssTuner->single_index_assembling_enabled()) u.resize(1);
    1173              : 
    1174              :         try{
    1175            0 :         for(size_t i = 0; i < vType.size(); ++i){
    1176            0 :                 int type = vType[i];
    1177            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1178            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1179            0 :                         if(m_vConstraint[i]->type() & type)
    1180              :                         {
    1181            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    1182            0 :                                 m_vConstraint[i]->adjust_solution(u, dd, type);
    1183              :                         }
    1184              :         }
    1185              : 
    1186            0 :         } UG_CATCH_THROW("Cannot adjust solution.");
    1187            0 : }
    1188              : 
    1189              : 
    1190              : 
    1191              : 
    1192              : //////////////////////////////////////////////////////////////////////////////
    1193              : //////////////////////////////////////////////////////////////////////////////
    1194              : //  Time Dependent (instationary)
    1195              : //////////////////////////////////////////////////////////////////////////////
    1196              : //////////////////////////////////////////////////////////////////////////////
    1197              : 
    1198              : ///////////////////////////////////////////////////////////////////////////////
    1199              : // Prepare Timestep (instationary)
    1200              : ///////////////////////////////////////////////////////////////////////////////
    1201              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1202            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1203              : prepare_timestep
    1204              : (
    1205              :         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1206              :         number future_time,
    1207              :         ConstSmartPtr<DoFDistribution> dd
    1208              : )
    1209              : {
    1210              :         PROFILE_FUNC_GROUP("discretization");
    1211              : //      update the elem discs
    1212              :         update_disc_items();
    1213            0 :         prep_assemble_loop(m_vElemDisc);
    1214              : 
    1215              : //      find out whether grid is regular
    1216              :         ConstSmartPtr<ISubsetHandler> sh = dd->subset_handler();
    1217            0 :         size_t num_subsets = sh->num_subsets();
    1218              :         bool bNonRegularGrid = false;
    1219            0 :         for (size_t si = 0; si < num_subsets; ++si)
    1220            0 :                 bNonRegularGrid |= !SubsetIsRegularGrid(*sh, si);
    1221              : 
    1222              : //      overrule by regular grid if required
    1223            0 :         if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1224              : 
    1225              : //      call assembler's PrepareTimestep
    1226              :         try
    1227              :         {
    1228            0 :                 gass_type::PrepareTimestep(m_vElemDisc, dd, bNonRegularGrid, vSol, future_time, m_spAssTuner);
    1229              :         }
    1230            0 :         UG_CATCH_THROW("DomainDiscretization::prepare_timestep (instationary):" <<
    1231              :                                    " Preparing time step failed.");
    1232              : 
    1233            0 :         post_assemble_loop(m_vElemDisc);
    1234            0 : }
    1235              : 
    1236              : ///////////////////////////////////////////////////////////////////////////////
    1237              : // Prepare Timestep Elem (instationary)
    1238              : ///////////////////////////////////////////////////////////////////////////////
    1239              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1240            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1241              : prepare_timestep_elem(ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1242              :                 ConstSmartPtr<DoFDistribution> dd)
    1243              : {
    1244              :         PROFILE_FUNC_GROUP("discretization");
    1245              : //      update the elem discs
    1246              :         update_disc_items();
    1247            0 :         prep_assemble_loop(m_vElemDisc);
    1248              : 
    1249              : //      Union of Subsets
    1250            0 :         SubsetGroup unionSubsets;
    1251              :         std::vector<SubsetGroup> vSSGrp;
    1252              : 
    1253              : //      create list of all subsets
    1254              :         try{
    1255            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1256            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1257              : 
    1258              : //      loop subsets
    1259            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1260              :         {
    1261              :         //      get subset
    1262              :                 const int si = unionSubsets[i];
    1263              : 
    1264              :         //      get dimension of the subset
    1265            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1266              : 
    1267              :         //      request if subset is regular grid
    1268            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1269              : 
    1270              :         //      overrule by regular grid if required
    1271            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1272              : 
    1273              :         //      Elem Disc on the subset
    1274              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1275              : 
    1276              :         //      get all element discretizations that work on the subset
    1277            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1278              : 
    1279              :         //      assemble on suitable elements
    1280              :                 try
    1281              :                 {
    1282            0 :                 switch(dim)
    1283              :                 {
    1284              :                 case 0:
    1285              :                         this->template PrepareTimestepElem<RegularVertex>
    1286            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1287            0 :                         break;
    1288              :                 case 1:
    1289              :                         this->template PrepareTimestepElem<RegularEdge>
    1290            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1291              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1292              :                         this->template PrepareTimestepElem<ConstrainingEdge>
    1293            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1294            0 :                         break;
    1295              :                 case 2:
    1296              :                         this->template PrepareTimestepElem<Triangle>
    1297            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1298              :                         this->template PrepareTimestepElem<Quadrilateral>
    1299            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1300              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1301              :                         this->template PrepareTimestepElem<ConstrainingTriangle>
    1302            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1303              :                         this->template PrepareTimestepElem<ConstrainingQuadrilateral>
    1304            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1305            0 :                         break;
    1306              :                 case 3:
    1307              :                         this->template PrepareTimestepElem<Tetrahedron>
    1308            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1309              :                         this->template PrepareTimestepElem<Pyramid>
    1310            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1311              :                         this->template PrepareTimestepElem<Prism>
    1312            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1313              :                         this->template PrepareTimestepElem<Hexahedron>
    1314            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1315              :                         this->template PrepareTimestepElem<Octahedron>
    1316            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    1317            0 :                         break;
    1318            0 :                 default:
    1319            0 :                         UG_THROW("DomainDiscretization::prepare_timestep_elem (instationary):"
    1320              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1321              :                 }
    1322              :                 }
    1323            0 :                 UG_CATCH_THROW("DomainDiscretization::prepare_timestep_elem (instationary):"
    1324              :                                                 " Assembling of elements of Dimension " << dim << " in "
    1325              :                                                 " subset "<<si<< " failed.");
    1326              :         }
    1327            0 :         post_assemble_loop(m_vElemDisc);
    1328            0 : }
    1329              : 
    1330              : /**
    1331              :  * This function prepares the global discretization for a time-stepping scheme
    1332              :  * by calling the "prepare_timestep_elem" methods of all passed element
    1333              :  * discretizations on one given subset.
    1334              :  *
    1335              :  * \param[in]           vElemDisc               element discretizations
    1336              :  * \param[in]           dd                              DoF Distribution
    1337              :  * \param[in]           si                              subset index
    1338              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1339              :  * \param[in]           vSol                    current and previous solutions
    1340              :  */
    1341              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1342              : template <typename TElem>
    1343            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1344              : PrepareTimestepElem(const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1345              :                                 ConstSmartPtr<DoFDistribution> dd,
    1346              :                                 int si, bool bNonRegularGrid,
    1347              :                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol)
    1348              : {
    1349              :         //      check if only some elements are selected
    1350            0 :         if(m_spAssTuner->selected_elements_used())
    1351              :         {
    1352              :                 std::vector<TElem*> vElem;
    1353            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    1354              : 
    1355              :                 //      assembling is carried out only over those elements
    1356              :                 //      which are selected and in subset si
    1357              :                 gass_type::template PrepareTimestepElem<TElem>
    1358            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    1359              :                          bNonRegularGrid, vSol, m_spAssTuner);
    1360            0 :         }
    1361              :         else
    1362              :         {
    1363              :                 //      general case: assembling over all elements in subset si
    1364              :                 gass_type::template PrepareTimestepElem<TElem>
    1365            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    1366              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    1367              :                                         bNonRegularGrid, vSol, m_spAssTuner);
    1368              :         }
    1369            0 : }
    1370              : 
    1371              : ///////////////////////////////////////////////////////////////////////////////
    1372              : // Jacobian (instationary)
    1373              : ///////////////////////////////////////////////////////////////////////////////
    1374              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1375            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1376              : assemble_jacobian(matrix_type& J,
    1377              :                   ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1378              :                   const number s_a0,
    1379              :                   ConstSmartPtr<DoFDistribution> dd)
    1380              : {
    1381              :         // do not do anything if matrix is supposed to be const
    1382            0 :         if (m_spAssTuner->matrix_is_const()) return;
    1383              : 
    1384              :         PROFILE_FUNC_GROUP("discretization");
    1385              : //      update the elem discs
    1386              :         update_disc_items();
    1387            0 :         prep_assemble_loop(m_vElemDisc);
    1388              : 
    1389              : //      reset matrix to zero and resize
    1390            0 :         m_spAssTuner->resize(dd, J);
    1391              : 
    1392              : //      get current time
    1393              :         const number time = vSol->time(0);
    1394              : 
    1395              : //      Union of Subsets
    1396            0 :         SubsetGroup unionSubsets;
    1397              :         std::vector<SubsetGroup> vSSGrp;
    1398              : 
    1399              : //      create list of all subsets
    1400              :         try{
    1401            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1402            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1403              : 
    1404              : //      preprocess -  modifies the solution, used for computing the defect
    1405              :         ConstSmartPtr<VectorTimeSeries<vector_type> > pModifyU = vSol;
    1406              :         SmartPtr<VectorTimeSeries<vector_type> > pModifyMemory;
    1407            0 :         if( m_spAssTuner->modify_solution_enabled() ){
    1408            0 :                 pModifyMemory = vSol->clone();
    1409            0 :                 pModifyU = pModifyMemory;
    1410              :                 try{
    1411            0 :                 for(int type = 1; type < CT_ALL; type = type << 1){
    1412            0 :                         if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1413            0 :                         for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1414            0 :                                 if(m_vConstraint[i]->type() & type)
    1415            0 :                                         m_vConstraint[i]->modify_solution(pModifyMemory, vSol, dd, type);
    1416              :                 }
    1417            0 :                 } UG_CATCH_THROW("'DomainDiscretization': Cannot modify solution.");
    1418              :         }
    1419              : 
    1420              : //      loop subsets
    1421            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1422              :         {
    1423              :         //      get subset
    1424              :                 const int si = unionSubsets[i];
    1425              : 
    1426              :         //      get dimension of the subset
    1427            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1428              : 
    1429              :         //      request if subset is regular grid
    1430            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1431              : 
    1432              :         //      overrule by regular grid if required
    1433            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1434              : 
    1435              :         //      Elem Disc on the subset
    1436              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1437              : 
    1438              :         //      get all element discretizations that work on the subset
    1439            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1440              : 
    1441              :         //      assemble on suitable elements
    1442              :                 try
    1443              :                 {
    1444            0 :                 switch(dim)
    1445              :                 {
    1446              :                 case 0:
    1447              :                         this->template AssembleJacobian<RegularVertex>
    1448            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1449            0 :                         break;
    1450              :                 case 1:
    1451              :                         this->template AssembleJacobian<RegularEdge>
    1452            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1453              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1454              :                         this->template AssembleJacobian<ConstrainingEdge>
    1455            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1456            0 :                         break;
    1457              :                 case 2:
    1458              :                         this->template AssembleJacobian<Triangle>
    1459            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1460              :                         this->template AssembleJacobian<Quadrilateral>
    1461            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1462              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1463              :                         this->template AssembleJacobian<ConstrainingTriangle>
    1464            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1465              :                         this->template AssembleJacobian<ConstrainingQuadrilateral>
    1466            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1467            0 :                         break;
    1468              :                 case 3:
    1469              :                         this->template AssembleJacobian<Tetrahedron>
    1470            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1471              :                         this->template AssembleJacobian<Pyramid>
    1472            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1473              :                         this->template AssembleJacobian<Prism>
    1474            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1475              :                         this->template AssembleJacobian<Hexahedron>
    1476            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1477              :                         this->template AssembleJacobian<Octahedron>
    1478            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, J, pModifyU, s_a0);
    1479            0 :                         break;
    1480            0 :                 default:
    1481            0 :                         UG_THROW("DomainDiscretization::assemble_jacobian (instationary):"
    1482              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1483              :                 }
    1484              :                 }
    1485            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_jacobian (instationary):"
    1486              :                                                 " Assembling of elements of Dimension " << dim << " in "
    1487              :                                                 " subset "<<si<< " failed.");
    1488              :         }
    1489              : 
    1490              : //      post process
    1491              :         try{
    1492            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
    1493            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1494            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1495            0 :                         if(m_vConstraint[i]->type() & type)
    1496              :                         {
    1497            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    1498            0 :                                 m_vConstraint[i]->adjust_jacobian(J, *pModifyU->solution(0), dd, type, time, pModifyU,s_a0);
    1499              :                         }
    1500              :         }
    1501            0 :         post_assemble_loop(m_vElemDisc);
    1502            0 :         }UG_CATCH_THROW("Cannot adjust jacobian.");
    1503              : 
    1504              : //      Remember parallel storage type
    1505              : #ifdef UG_PARALLEL
    1506              :         J.set_storage_type(PST_ADDITIVE);
    1507              :         J.set_layouts(dd->layouts());
    1508              : #endif
    1509            0 : }
    1510              : 
    1511              : /**
    1512              :  * This function adds the contributions of all passed element discretizations
    1513              :  * on one given subset to the global Jacobian in the time-dependent case.
    1514              :  * Note, that s_m0 == 1
    1515              :  *
    1516              :  * \param[in]           vElemDisc               element discretizations
    1517              :  * \param[in]           dd                              DoF Distribution
    1518              :  * \param[in]           si                              subset index
    1519              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1520              :  * \param[in,out]       J                               jacobian
    1521              :  * \param[in]           vSol                    current and previous solutions
    1522              :  * \param[in]           s_a0                    scaling factor for stiffness part
    1523              :  */
    1524              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1525              : template <typename TElem>
    1526            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1527              : AssembleJacobian(       const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1528              :                                         ConstSmartPtr<DoFDistribution> dd,
    1529              :                                         int si, bool bNonRegularGrid,
    1530              :                                         matrix_type& J,
    1531              :                                         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1532              :                                         number s_a0)
    1533              : {
    1534              :         //      check if only some elements are selected
    1535            0 :         if(m_spAssTuner->selected_elements_used())
    1536              :         {
    1537              :                 std::vector<TElem*> vElem;
    1538            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    1539              :         
    1540              :                 //      assembling is carried out only over those elements
    1541              :                 //      which are selected and in subset si
    1542              :                 gass_type::template AssembleJacobian<TElem>
    1543            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    1544              :                          bNonRegularGrid, J, vSol, s_a0, m_spAssTuner);
    1545            0 :         }
    1546              :         else
    1547              :         {
    1548              :                 gass_type::template AssembleJacobian<TElem>
    1549            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    1550              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    1551              :                                         bNonRegularGrid, J, vSol, s_a0, m_spAssTuner);
    1552              :         }
    1553            0 : }
    1554              : 
    1555              : ///////////////////////////////////////////////////////////////////////////////
    1556              : // Defect (instationary)
    1557              : ///////////////////////////////////////////////////////////////////////////////
    1558              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1559            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1560              : assemble_defect(vector_type& d,
    1561              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1562              :                 const std::vector<number>& vScaleMass,
    1563              :                 const std::vector<number>& vScaleStiff,
    1564              :                 ConstSmartPtr<DoFDistribution> dd)
    1565              : {
    1566              :         PROFILE_FUNC_GROUP("discretization");
    1567              : //      update the elem discs
    1568              :         update_disc_items();
    1569            0 :         prep_assemble_loop(m_vElemDisc);
    1570              : 
    1571              : //      reset vector to zero and resize
    1572            0 :         m_spAssTuner->resize(dd, d);
    1573              : 
    1574              : //      Union of Subsets
    1575            0 :         SubsetGroup unionSubsets;
    1576              :         std::vector<SubsetGroup> vSSGrp;
    1577              : 
    1578              : //      create list of all subsets
    1579              :         try{
    1580            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1581            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1582              : 
    1583              : //      pre process -  modifies the solution, used for computing the defect
    1584              :         ConstSmartPtr<VectorTimeSeries<vector_type> > pModifyU = vSol;
    1585              :         SmartPtr<VectorTimeSeries<vector_type> > pModifyMemory;
    1586            0 :         if( m_spAssTuner->modify_solution_enabled() ){
    1587            0 :                 pModifyMemory = vSol->clone();
    1588            0 :                 pModifyU = pModifyMemory;
    1589              :                 try{
    1590            0 :                 for(int type = 1; type < CT_ALL; type = type << 1){
    1591            0 :                         if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1592            0 :                         for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1593            0 :                                 if(m_vConstraint[i]->type() & type)
    1594            0 :                                         m_vConstraint[i]->modify_solution(pModifyMemory, vSol, dd, type);
    1595              :                 }
    1596            0 :                 } UG_CATCH_THROW("'DomainDiscretization: Cannot modify solution.");
    1597              :         }
    1598              : 
    1599              : //      loop subsets
    1600            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1601              :         {
    1602              :         //      get subset
    1603              :                 const int si = unionSubsets[i];
    1604              : 
    1605              :         //      get dimension of the subset
    1606            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1607              : 
    1608              :         //      request if subset is regular grid
    1609            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1610              : 
    1611              :         //      overrule by regular grid if required
    1612            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1613              : 
    1614              :         //      Elem Disc on the subset
    1615              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1616              : 
    1617              :         //      get all element discretizations that work on the subset
    1618            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1619              : 
    1620              :         //      assemble on suitable elements
    1621              :                 try
    1622              :                 {
    1623            0 :                 switch(dim)
    1624              :                 {
    1625              :                 case 0:
    1626              :                         this->template AssembleDefect<RegularVertex>
    1627            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1628            0 :                         break;
    1629              :                 case 1:
    1630              :                         this->template AssembleDefect<RegularEdge>
    1631            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1632              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1633              :                         this->template AssembleDefect<ConstrainingEdge>
    1634            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1635            0 :                         break;
    1636              :                 case 2:
    1637              :                         this->template AssembleDefect<Triangle>
    1638            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1639              :                         this->template AssembleDefect<Quadrilateral>
    1640            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1641              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1642              :                         this->template AssembleDefect<ConstrainingTriangle>
    1643            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1644              :                         this->template AssembleDefect<ConstrainingQuadrilateral>
    1645            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1646            0 :                         break;
    1647              :                 case 3:
    1648              :                         this->template AssembleDefect<Tetrahedron>
    1649            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1650              :                         this->template AssembleDefect<Pyramid>
    1651            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1652              :                         this->template AssembleDefect<Prism>
    1653            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1654              :                         this->template AssembleDefect<Hexahedron>
    1655            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1656              :                         this->template AssembleDefect<Octahedron>
    1657            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, d, pModifyU, vScaleMass, vScaleStiff);
    1658            0 :                         break;
    1659            0 :                 default:
    1660            0 :                         UG_THROW("DomainDiscretization::assemble_defect (instationary):"
    1661              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1662              :                 }
    1663              :                 }
    1664            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_defect (instationary):"
    1665              :                                                 " Assembling of elements of Dimension " << dim << " in"
    1666              :                                                 " subset "<< si << " failed.");
    1667              :         }
    1668              : 
    1669              : //      post process
    1670              :         try{
    1671            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
    1672            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1673            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1674            0 :                         if(m_vConstraint[i]->type() & type)
    1675              :                         {
    1676            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    1677            0 :                                 m_vConstraint[i]->adjust_defect(d, *pModifyU->solution(0), dd, type, pModifyU->time(0), pModifyU, &vScaleMass, &vScaleStiff);
    1678              :                         }
    1679              :         }
    1680            0 :         post_assemble_loop(m_vElemDisc);
    1681            0 :         } UG_CATCH_THROW("Cannot adjust defect.");
    1682              : 
    1683              : //      Remember parallel storage type
    1684              : #ifdef UG_PARALLEL
    1685              :         d.set_storage_type(PST_ADDITIVE);
    1686              : #endif
    1687            0 : }
    1688              : 
    1689              : /*
    1690              :  * This function adds the contributions of all passed element discretizations
    1691              :  * on one given subset to the global Defect in the instationary case.
    1692              :  *
    1693              :  * \param[in]           vElemDisc               element discretizations
    1694              :  * \param[in]           dd                              DoF Distribution
    1695              :  * \param[in]           si                              subset index
    1696              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1697              :  * \param[in,out]       d                               defect
    1698              :  * \param[in]           vSol                    current and previous solutions
    1699              :  * \param[in]           vScaleMass              scaling factors for mass part
    1700              :  * \param[in]           vScaleStiff             scaling factors for stiffness part
    1701              :  */
    1702              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1703              : template <typename TElem>
    1704            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1705              : AssembleDefect( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1706              :                                 ConstSmartPtr<DoFDistribution> dd,
    1707              :                                 int si, bool bNonRegularGrid,
    1708              :                                 vector_type& d,
    1709              :                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1710              :                                 const std::vector<number>& vScaleMass,
    1711              :                                 const std::vector<number>& vScaleStiff)
    1712              : {
    1713              :         //      check if only some elements are selected
    1714            0 :         if(m_spAssTuner->selected_elements_used())
    1715              :         {
    1716              :                 std::vector<TElem*> vElem;
    1717            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    1718              :                 
    1719              :                 //      assembling is carried out only over those elements
    1720              :                 //      which are selected and in subset si
    1721              :                 gass_type::template AssembleDefect<TElem>
    1722            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    1723              :                          bNonRegularGrid, d, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    1724            0 :         }
    1725              :         else
    1726              :         {
    1727              :                 //      general case: assembling over all elements in subset si
    1728              :                 gass_type::template AssembleDefect<TElem>
    1729            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    1730              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    1731              :                                         bNonRegularGrid, d, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    1732              :         }
    1733            0 : }
    1734              : 
    1735              : ///////////////////////////////////////////////////////////////////////////////
    1736              : // Matrix and RHS (instationary)
    1737              : ///////////////////////////////////////////////////////////////////////////////
    1738              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1739            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1740              : assemble_linear(matrix_type& mat, vector_type& rhs,
    1741              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1742              :                 const std::vector<number>& vScaleMass,
    1743              :                 const std::vector<number>& vScaleStiff,
    1744              :                 ConstSmartPtr<DoFDistribution> dd)
    1745              : {
    1746              :         PROFILE_FUNC_GROUP("discretization");
    1747              : //      update the elem discs
    1748              :         update_disc_items();
    1749              : 
    1750              : //      reset matrix to zero and resize
    1751            0 :         if (!m_spAssTuner->matrix_is_const())
    1752            0 :                 m_spAssTuner->resize(dd, mat);
    1753            0 :         m_spAssTuner->resize(dd, rhs);
    1754              : 
    1755              : //      Union of Subsets
    1756            0 :         SubsetGroup unionSubsets;
    1757              :         std::vector<SubsetGroup> vSSGrp;
    1758              : 
    1759              : //      create list of all subsets
    1760              :         try{
    1761            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1762            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1763              : 
    1764              : //      loop subsets
    1765            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1766              :         {
    1767              :         //      get subset
    1768              :                 const int si = unionSubsets[i];
    1769              : 
    1770              :         //      get dimension of the subset
    1771            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1772              : 
    1773              :         //      request if subset is regular grid
    1774            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1775              : 
    1776              :         //      overrule by regular grid if required
    1777            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1778              : 
    1779              :         //      Elem Disc on the subset
    1780              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1781              : 
    1782              :         //      get all element discretizations that work on the subset
    1783            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1784              : 
    1785              :         //      assemble on suitable elements
    1786              :                 try
    1787              :                 {
    1788            0 :                 switch(dim)
    1789              :                 {
    1790              :                 case 0:
    1791              :                         this->template AssembleLinear<RegularVertex>
    1792            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1793            0 :                         break;
    1794              :                 case 1:
    1795              :                         this->template AssembleLinear<RegularEdge>
    1796            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1797              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1798              :                         this->template AssembleLinear<ConstrainingEdge>
    1799            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1800            0 :                         break;
    1801              :                 case 2:
    1802              :                         this->template AssembleLinear<Triangle>
    1803            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1804              :                         this->template AssembleLinear<Quadrilateral>
    1805            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1806              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1807              :                         this->template AssembleLinear<ConstrainingTriangle>
    1808            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1809              :                         this->template AssembleLinear<ConstrainingQuadrilateral>
    1810            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1811            0 :                         break;
    1812              :                 case 3:
    1813              :                         this->template AssembleLinear<Tetrahedron>
    1814            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1815              :                         this->template AssembleLinear<Pyramid>
    1816            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1817              :                         this->template AssembleLinear<Prism>
    1818            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1819              :                         this->template AssembleLinear<Hexahedron>
    1820            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1821              :                         this->template AssembleLinear<Octahedron>
    1822            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, mat, rhs, vSol, vScaleMass, vScaleStiff);
    1823            0 :                         break;
    1824            0 :                 default:
    1825            0 :                         UG_THROW("DomainDiscretization::assemble_linear (instationary):"
    1826              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1827              :                 }
    1828              :                 }
    1829            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_linear (instationary):"
    1830              :                                                 " Assembling of elements of Dimension " << dim << " in "
    1831              :                                                 " subset "<<si<< " failed.");
    1832              :         }
    1833              : 
    1834              : //      post process
    1835              :         try{
    1836            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
    1837            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    1838            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    1839            0 :                         if(m_vConstraint[i]->type() & type)
    1840              :                         {
    1841            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    1842            0 :                                 m_vConstraint[i]->adjust_linear(mat, rhs, dd, type, vSol->time(0));
    1843              :                         }
    1844              :         }
    1845            0 :         } UG_CATCH_THROW("Cannot adjust linear.");
    1846              : 
    1847              : //      Remember parallel storage type
    1848              : #ifdef UG_PARALLEL
    1849              :         mat.set_storage_type(PST_ADDITIVE);
    1850              :         mat.set_layouts(dd->layouts());
    1851              : 
    1852              :         rhs.set_storage_type(PST_ADDITIVE);
    1853              : #endif
    1854            0 : }
    1855              : 
    1856              : /**
    1857              :  * This function adds the contributions of all passed element discretizations
    1858              :  * on one given subset to the global Matrix and the global Right-Hand Side
    1859              :  * of the Linear problem in the stationary case.
    1860              :  *
    1861              :  * \param[in]           vElemDisc               element discretizations
    1862              :  * \param[in]           dd                              DoF Distribution
    1863              :  * \param[in]           si                              subset index
    1864              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1865              :  * \param[in,out]       A                               Matrix
    1866              :  * \param[in,out]       rhs                             Right-hand side
    1867              :  * \param[in]           vSol                    current and previous solutions
    1868              :  * \param[in]           vScaleMass              scaling factors for mass part
    1869              :  * \param[in]           vScaleStiff             scaling factors for stiffness part
    1870              :  */
    1871              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1872              : template <typename TElem>
    1873            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1874              : AssembleLinear( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1875              :                                 ConstSmartPtr<DoFDistribution> dd,
    1876              :                                 int si, bool bNonRegularGrid,
    1877              :                                 matrix_type& A,
    1878              :                                 vector_type& rhs,
    1879              :                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1880              :                                 const std::vector<number>& vScaleMass,
    1881              :                                 const std::vector<number>& vScaleStiff)
    1882              : {
    1883              :         //      check if only some elements are selected
    1884            0 :         if(m_spAssTuner->selected_elements_used())
    1885              :         {
    1886              :                 std::vector<TElem*> vElem;
    1887            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    1888              : 
    1889              :                 //      assembling is carried out only over those elements
    1890              :                 //      which are selected and in subset si
    1891              :                 gass_type::template AssembleLinear<TElem>
    1892            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    1893              :                          bNonRegularGrid, A, rhs, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    1894            0 :         }
    1895              :         else
    1896              :         {
    1897              :                 //      general case: assembling over all elements in subset si
    1898              :                 gass_type::template AssembleLinear<TElem>
    1899            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    1900              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    1901              :                                         bNonRegularGrid, A, rhs, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    1902              :         }
    1903            0 : }
    1904              : 
    1905              : ///////////////////////////////////////////////////////////////////////////////
    1906              : // RHS (instationary)
    1907              : ///////////////////////////////////////////////////////////////////////////////
    1908              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    1909            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    1910              : assemble_rhs(vector_type& rhs,
    1911              :              ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1912              :              const std::vector<number>& vScaleMass,
    1913              :              const std::vector<number>& vScaleStiff,
    1914              :              ConstSmartPtr<DoFDistribution> dd)
    1915              : {
    1916              :         PROFILE_FUNC_GROUP("discretization");
    1917              : //      update the elem discs
    1918              :         update_disc_items();
    1919              : 
    1920              : //      reset vector to zero and resize
    1921            0 :         m_spAssTuner->resize(dd, rhs);
    1922              : 
    1923              : //      Union of Subsets
    1924            0 :         SubsetGroup unionSubsets;
    1925              :         std::vector<SubsetGroup> vSSGrp;
    1926              : 
    1927              : //      create list of all subsets
    1928              :         try{
    1929            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    1930            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    1931              : 
    1932              : //      loop subsets
    1933            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    1934              :         {
    1935              :         //      get subset
    1936              :                 const int si = unionSubsets[i];
    1937              : 
    1938              :         //      get dimension of the subset
    1939            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    1940              : 
    1941              :         //      request if subset is regular grid
    1942            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    1943              : 
    1944              :         //      overrule by regular grid if required
    1945            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    1946              : 
    1947              :         //      Elem Disc on the subset
    1948              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    1949              : 
    1950              :         //      get all element discretizations that work on the subset
    1951            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    1952              : 
    1953              :         //      assemble on suitable elements
    1954              :                 try
    1955              :                 {
    1956            0 :                 switch(dim)
    1957              :                 {
    1958              :                 case 0:
    1959              :                         this->template AssembleRhs<RegularVertex>
    1960            0 :                                  (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1961            0 :                         break;
    1962              :                 case 1:
    1963              :                         this->template AssembleRhs<RegularEdge>
    1964            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1965              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1966              :                         this->template AssembleRhs<ConstrainingEdge>
    1967            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1968            0 :                         break;
    1969              :                 case 2:
    1970              :                         this->template AssembleRhs<Triangle>
    1971            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1972              :                         this->template AssembleRhs<Quadrilateral>
    1973            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1974              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    1975              :                         this->template AssembleRhs<ConstrainingTriangle>
    1976            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1977              :                         this->template AssembleRhs<ConstrainingQuadrilateral>
    1978            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1979            0 :                         break;
    1980              :                 case 3:
    1981              :                         this->template AssembleRhs<Tetrahedron>
    1982            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1983              :                         this->template AssembleRhs<Pyramid>
    1984            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1985              :                         this->template AssembleRhs<Prism>
    1986            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1987              :                         this->template AssembleRhs<Hexahedron>
    1988            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1989              :                         this->template AssembleRhs<Octahedron>
    1990            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff);
    1991            0 :                         break;
    1992            0 :                 default:
    1993            0 :                         UG_THROW("DomainDiscretization::assemble_rhs (instationary):"
    1994              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    1995              :                 }
    1996              :                 }
    1997            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_rhs (instationary):"
    1998              :                                                 " Assembling of elements of Dimension " << dim << " in "
    1999              :                                                 " subset "<<si<< " failed.");
    2000              :         }
    2001              : 
    2002              : 
    2003              : //      post process
    2004              :         try{
    2005            0 :         for(int type = 1; type < CT_ALL; type = type << 1){
    2006            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    2007            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    2008            0 :                         if(m_vConstraint[i]->type() & type)
    2009              :                         {
    2010            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    2011            0 :                                 m_vConstraint[i]->adjust_rhs(rhs, *(vSol->solution(0)), dd, type, vSol->time(0));
    2012              :                         }
    2013              :         }
    2014            0 :         } UG_CATCH_THROW("Cannot adjust linear.");
    2015              : 
    2016              : //      Remember parallel storage type
    2017              : #ifdef UG_PARALLEL
    2018              :         rhs.set_storage_type(PST_ADDITIVE);
    2019              : #endif
    2020            0 : }
    2021              : 
    2022              : /**
    2023              :  * This function adds the contributions of all passed element discretizations
    2024              :  * on one given subset to the global Right-Hand Side in the time-dependent case.
    2025              :  *
    2026              :  * \param[in]           vElemDisc               element discretizations
    2027              :  * \param[in]           dd                              DoF Distribution
    2028              :  * \param[in]           si                              subset index
    2029              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2030              :  * \param[in,out]       rhs                             Right-hand side
    2031              :  * \param[in]           vSol                    current and previous solutions
    2032              :  * \param[in]           vScaleMass              scaling factors for mass part
    2033              :  * \param[in]           vScaleStiff             scaling factors for stiffness part
    2034              :  */
    2035              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2036              : template <typename TElem>
    2037            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2038              : AssembleRhs(    const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    2039              :                                 ConstSmartPtr<DoFDistribution> dd,
    2040              :                                 int si, bool bNonRegularGrid,
    2041              :                                 vector_type& rhs,
    2042              :                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    2043              :                                 const std::vector<number>& vScaleMass,
    2044              :                                 const std::vector<number>& vScaleStiff)
    2045              : {
    2046              :         //      check if only some elements are selected
    2047            0 :         if(m_spAssTuner->selected_elements_used())
    2048              :         {
    2049              :                 std::vector<TElem*> vElem;
    2050            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    2051              : 
    2052              :                 //      assembling is carried out only over those elements
    2053              :                 //      which are selected and in subset si
    2054              :                 gass_type::template AssembleRhs<TElem>
    2055            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    2056              :                          bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    2057            0 :         }
    2058              :         else
    2059              :         {
    2060              :                 //      general case: assembling over all elements in subset si
    2061              :                 gass_type::template AssembleRhs<TElem>
    2062            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    2063              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    2064              :                                         bNonRegularGrid, rhs, vSol, vScaleMass, vScaleStiff, m_spAssTuner);
    2065              :         }
    2066            0 : }
    2067              : 
    2068              : ///////////////////////////////////////////////////////////////////////////////
    2069              : // set constraint values (instationary)
    2070              : ///////////////////////////////////////////////////////////////////////////////
    2071              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2072            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2073              : adjust_solution(vector_type& u, number time, ConstSmartPtr<DoFDistribution> dd)
    2074              : {
    2075              :         PROFILE_FUNC_GROUP("discretization");
    2076            0 :         update_constraints();
    2077              : 
    2078              :         // NOTE: it is crucial, that dirichlet pp are processed before constraints.
    2079              :         //               otherwise we may start with an inconsistent solution in the solvers
    2080            0 :         std::vector<int> vType(5);
    2081            0 :         vType[0] = CT_DIRICHLET;        // hanging (or other constrained) nodes might depend on Dirichlet nodes
    2082            0 :         vType[1] = CT_CONSTRAINTS;
    2083            0 :         vType[2] = CT_HANGING;
    2084            0 :         vType[3] = CT_MAY_DEPEND_ON_HANGING;
    2085            0 :         vType[4] = CT_DIRICHLET;        // hanging DoFs might be Dirichlet (Dirichlet overrides)
    2086              : 
    2087              :         // if assembling is carried out at one DoF only, u needs to be resized
    2088            0 :         if (m_spAssTuner->single_index_assembling_enabled()) u.resize(1);
    2089              : 
    2090              :         try{
    2091              : 
    2092              : //      constraints
    2093            0 :         for(size_t i = 0; i < vType.size(); ++i){
    2094            0 :                 int type = vType[i];
    2095            0 :                 if(!(m_spAssTuner->constraint_type_enabled(type))) continue;
    2096            0 :                 for(size_t i = 0; i < m_vConstraint.size(); ++i)
    2097            0 :                         if(m_vConstraint[i]->type() & type)
    2098              :                         {
    2099            0 :                                 m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    2100            0 :                                 m_vConstraint[i]->adjust_solution(u, dd, type, time);
    2101              :                         }
    2102              :         }
    2103            0 :         } UG_CATCH_THROW(" Cannot adjust solution.");
    2104            0 : }
    2105              : 
    2106              : ///////////////////////////////////////////////////////////////////////////////
    2107              : // Initialization of the exports (optional)
    2108              : ///////////////////////////////////////////////////////////////////////////////
    2109              : 
    2110              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2111            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2112              : init_all_exports(ConstSmartPtr<DoFDistribution> dd, bool bAsTimeDependent)
    2113              : {
    2114              :         PROFILE_FUNC_GROUP("discretization");
    2115              : //      update the elem discs
    2116              :         update_disc_items();
    2117              : 
    2118              : //      Union of Subsets
    2119            0 :         SubsetGroup unionSubsets;
    2120              :         std::vector<SubsetGroup> vSSGrp;
    2121              : 
    2122              : //      create list of all subsets
    2123              :         try{
    2124            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    2125            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    2126              : 
    2127              : //      loop subsets
    2128            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    2129              :         {
    2130              :         //      get subset
    2131              :                 const int si = unionSubsets[i];
    2132              : 
    2133              :         //      get dimension of the subset
    2134            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    2135              : 
    2136              :         //      request if subset is regular grid
    2137            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    2138              : 
    2139              :         //      overrule by regular grid if required
    2140            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    2141              : 
    2142              :         //      Elem Disc on the subset
    2143              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    2144              : 
    2145              :         //      get all element discretizations that work on the subset
    2146            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    2147              : 
    2148              :         //      assemble on suitable elements
    2149              :                 try
    2150              :                 {
    2151            0 :                 switch(dim)
    2152              :                 {
    2153            0 :                 case 0:
    2154              :                         this->template InitAllExports<RegularVertex>
    2155            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2156            0 :                         break;
    2157            0 :                 case 1:
    2158              :                         this->template InitAllExports<RegularEdge>
    2159            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2160              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    2161              :                         this->template InitAllExports<ConstrainingEdge>
    2162            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2163            0 :                         break;
    2164            0 :                 case 2:
    2165              :                         this->template InitAllExports<Triangle>
    2166            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2167              :                         this->template InitAllExports<Quadrilateral>
    2168            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2169              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    2170              :                         this->template InitAllExports<ConstrainingTriangle>
    2171            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2172              :                         this->template InitAllExports<ConstrainingQuadrilateral>
    2173            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2174            0 :                         break;
    2175            0 :                 case 3:
    2176              :                         this->template InitAllExports<Tetrahedron>
    2177            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2178              :                         this->template InitAllExports<Pyramid>
    2179            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2180              :                         this->template InitAllExports<Prism>
    2181            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2182              :                         this->template InitAllExports<Hexahedron>
    2183            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2184              :                         this->template InitAllExports<Octahedron>
    2185            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, bAsTimeDependent);
    2186            0 :                         break;
    2187            0 :                 default:
    2188            0 :                         UG_THROW("DomainDiscretization::init_all_exports:"
    2189              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    2190              :                 }
    2191              :                 }
    2192            0 :                 UG_CATCH_THROW("DomainDiscretization::assemble_stiffness_matrix:"
    2193              :                                         " Assembling of elements of Dimension " << dim << " in "
    2194              :                                         " subset "<<si<< " failed.");
    2195              :         }
    2196              : 
    2197            0 : }
    2198              : 
    2199              : /**
    2200              :  * This function initalizes the exports and does not do anything else.
    2201              :  *
    2202              :  * It transfers the dof distributions to the exports and creates the function
    2203              :  * maps there.
    2204              :  *
    2205              :  * This initizalization is optional but after that, the exports can be used
    2206              :  * by other objects (like in the plotting).
    2207              :  *
    2208              :  * \param[in]           vElemDisc               element discretizations
    2209              :  * \param[in]           dd                              DoF Distribution
    2210              :  * \param[in]           si                              subset index
    2211              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2212              :  * \param[in]           bAsTimeDependent flag to simulate the instationary case for the initialization
    2213              :  */
    2214              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2215              : template <typename TElem>
    2216            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2217              : InitAllExports( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    2218              :                                                         ConstSmartPtr<DoFDistribution> dd,
    2219              :                                                         int si, bool bNonRegularGrid, bool bAsTimeDependent)
    2220              : {
    2221              :         //      check if only some elements are selected
    2222            0 :         if(m_spAssTuner->selected_elements_used())
    2223              :         {
    2224              :                 std::vector<TElem*> vElem;
    2225            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    2226              : 
    2227              :                 //      assembling is carried out only over those elements
    2228              :                 //      which are selected and in subset si
    2229              :                 gass_type::template InitAllExports<TElem>
    2230            0 :                         (vElemDisc, dd, vElem.begin(), vElem.end(), si, bNonRegularGrid, bAsTimeDependent);
    2231            0 :         }
    2232              :         else
    2233              :         {
    2234              :                 //      general case: assembling over all elements in subset si
    2235              :                 gass_type::template InitAllExports<TElem>
    2236            0 :                         (vElemDisc, dd,
    2237              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    2238              :                                         bNonRegularGrid, bAsTimeDependent);
    2239              :         }
    2240            0 : }
    2241              : 
    2242              : ///////////////////////////////////////////////////////////////////////////////
    2243              : ///////////////////////////////////////////////////////////////////////////////
    2244              : // Error estimator
    2245              : ///////////////////////////////////////////////////////////////////////////////
    2246              : ///////////////////////////////////////////////////////////////////////////////
    2247              : 
    2248              : template <typename TDomain, typename T>
    2249            0 : void CollectIErrEstData(std::vector<IErrEstData<TDomain>*> &vErrEstData, const T &vElemDisc)
    2250              : {
    2251            0 :         for (std::size_t i = 0; i < vElemDisc.size(); ++i)
    2252              :         {
    2253            0 :                 SmartPtr<IErrEstData<TDomain> > sp_err_est_data = vElemDisc[i]->err_est_data();
    2254            0 :                 IErrEstData<TDomain>* err_est_data = sp_err_est_data.get();
    2255            0 :                         if (err_est_data == NULL) continue; // no data specified
    2256            0 :                         if (std::find (vErrEstData.begin(), vErrEstData.end(), err_est_data) != vErrEstData.end())
    2257            0 :                                 continue; // this one is already in the array
    2258            0 :                         if (err_est_data->consider_me()) vErrEstData.push_back(err_est_data);
    2259              :         }
    2260              : 
    2261            0 : }
    2262              : 
    2263              : ///////////////////////////////////////////////////////////////////////////////
    2264              : // Error estimator (stationary)
    2265              : ///////////////////////////////////////////////////////////////////////////////
    2266              : 
    2267              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2268            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2269              : calc_error
    2270              : (
    2271              :         const vector_type& u,
    2272              :         ConstSmartPtr<DoFDistribution> dd,
    2273              :         error_vector_type* u_vtk
    2274              : )
    2275              : {
    2276              :         PROFILE_FUNC_GROUP("error_estimator");
    2277              : 
    2278              : //      get multigrid
    2279              :         SmartPtr<MultiGrid> pMG = ((DoFDistribution *) dd.get())->multi_grid();
    2280              : 
    2281              : // check, whether separate error data exists
    2282              :         const bool useErrorData = !m_vDomainElemError.empty();
    2283              :         // UG_LOG("useErrorData=" << (useErrorData) << std::endl);
    2284              : 
    2285              : //      update the elem discs
    2286            0 :         if (useErrorData) { update_error_items();}
    2287              :         else { update_disc_items();}
    2288              : 
    2289              : //      Union of Subsets
    2290            0 :         SubsetGroup unionSubsets;
    2291              :         std::vector<SubsetGroup> vSSGrp;
    2292              : 
    2293              : //      create list of all subsets
    2294              :         try
    2295              :         {
    2296            0 :                 if (useErrorData) { CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemError, dd->subset_handler());}
    2297            0 :                 else { CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());}
    2298              :         }
    2299            0 :         UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    2300              : 
    2301              : //      get the error estimator data for all the discretizations
    2302              :         std::vector<IErrEstData<TDomain>*> vErrEstData;
    2303            0 :         if (useErrorData) CollectIErrEstData(vErrEstData, m_vElemError);
    2304            0 :         else  CollectIErrEstData(vErrEstData, m_vElemDisc);
    2305              :         /*for(std::size_t i = 0; i < m_vElemDisc.size(); ++i)
    2306              :         {
    2307              :                 SmartPtr<IErrEstData<TDomain> > sp_err_est_data = m_vElemDisc[i]->err_est_data();
    2308              :                 IErrEstData<TDomain>* err_est_data = sp_err_est_data.get();
    2309              :                 if (err_est_data == NULL) continue; // no data specified
    2310              :                 if (std::find (vErrEstData.begin(), vErrEstData.end(), err_est_data) != vErrEstData.end())
    2311              :                         continue; // this one is already in the array
    2312              :                 if (err_est_data->consider_me()) vErrEstData.push_back(err_est_data);
    2313              :         }*/
    2314              : 
    2315              : //      preprocess the error estimator data in the discretizations
    2316              :         try
    2317              :         {
    2318            0 :                 for (size_t i = 0; i < vErrEstData.size(); ++i)
    2319            0 :                         vErrEstData[i]->alloc_err_est_data(dd->surface_view(), dd->grid_level());
    2320              :         }
    2321            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot prepare the error estimator");
    2322              : 
    2323              : 
    2324              : 
    2325              : //      loop subsets to assemble the estimators
    2326            0 :         for (size_t i = 0; i < unionSubsets.size(); ++i)
    2327              :         {
    2328              :         //      get subset
    2329              :                 const int si = unionSubsets[i];
    2330              : 
    2331              :         //      get dimension of the subset
    2332            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    2333              : 
    2334              :         //      request if subset is regular grid
    2335            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    2336              : 
    2337              :         //      Elem Disc on the subset
    2338              :                 typedef typename std::vector<IElemError<TDomain>*> error_vector_type;
    2339              :                 error_vector_type vSubsetElemError;
    2340              : 
    2341              :         //      get all element discretizations that work on the subset
    2342            0 :                 GetElemDiscItemOnSubset<IElemError<TDomain>, IElemDisc<TDomain> > (vSubsetElemError, m_vElemDisc, vSSGrp, si);
    2343            0 :                 if (useErrorData)
    2344              :                 {
    2345              :                         GetElemDiscItemOnSubset<IElemError<TDomain>, IElemError<TDomain> >
    2346            0 :                         (vSubsetElemError, m_vElemError, vSSGrp, si);
    2347              :                 }
    2348              :                 else
    2349              :                 {
    2350              :                         GetElemDiscItemOnSubset<IElemError<TDomain>, IElemDisc<TDomain> >
    2351            0 :                         (vSubsetElemError, m_vElemDisc, vSSGrp, si);
    2352              :                 }
    2353              : 
    2354              :                 /*
    2355              :                 UG_LOG("m_vElemDisc.size="<<m_vElemDisc.size()<< std::endl);
    2356              :                 UG_LOG("m_vElemError.size="<<m_vElemError.size()<< std::endl);
    2357              :                 UG_LOG("vSubsetElemError.size="<<vSubsetElemError.size()<< std::endl);
    2358              :                 */
    2359              : 
    2360              :         //      remove from elemDisc list those with !err_est_enabled()
    2361              :                 typename error_vector_type::iterator it = vSubsetElemError.begin();
    2362            0 :                 while (it != vSubsetElemError.end())
    2363              :                 {
    2364            0 :                         if (!(*it)->err_est_enabled())
    2365              :                                 it = vSubsetElemError.erase(it);
    2366              :                         else ++it;
    2367              :                 }
    2368              :         //      UG_LOG("vSubsetElemError.size="<<vSubsetElemError.size()<< std::endl);
    2369              : 
    2370              :         //      assemble on suitable elements
    2371              :                 try
    2372              :                 {
    2373            0 :                         switch (dim)
    2374              :                         {
    2375            0 :                         case 1:
    2376              :                                 this->template AssembleErrorEstimator<RegularEdge>
    2377            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2378              :                                 // When assembling over lower-dim manifolds that contain hanging nodes:
    2379              :                                 this->template AssembleErrorEstimator<ConstrainingEdge>
    2380            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2381            0 :                                 break;
    2382            0 :                         case 2:
    2383              :                                 this->template AssembleErrorEstimator<Triangle>
    2384            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2385              :                                 this->template AssembleErrorEstimator<Quadrilateral>
    2386            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2387              :                                 // When assembling over lower-dim manifolds that contain hanging nodes:
    2388              :                                 this->template AssembleErrorEstimator<ConstrainingTriangle>
    2389            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2390              :                                 this->template AssembleErrorEstimator<ConstrainingQuadrilateral>
    2391            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2392            0 :                                 break;
    2393            0 :                         case 3:
    2394              :                                 this->template AssembleErrorEstimator<Tetrahedron>
    2395            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2396              :                                 this->template AssembleErrorEstimator<Pyramid>
    2397            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2398              :                                 this->template AssembleErrorEstimator<Prism>
    2399            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2400              :                                 this->template AssembleErrorEstimator<Hexahedron>
    2401            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2402              :                                 this->template AssembleErrorEstimator<Octahedron>
    2403            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, u);
    2404            0 :                                 break;
    2405            0 :                         default:
    2406            0 :                                 UG_THROW("DomainDiscretization::calc_error:"
    2407              :                                                                 " Dimension "<<dim<<" (subset="<<si<<") not supported.");
    2408              :                         }
    2409              :                 }
    2410            0 :                 UG_CATCH_THROW("DomainDiscretization::calc_error:"
    2411              :                                                 " Assembling of elements of Dimension " << dim << " in "
    2412              :                                                 " subset "<<si<< " failed.");
    2413              :         }
    2414              : 
    2415              : //      apply constraints
    2416              :         try
    2417              :         {
    2418            0 :                 for (int type = 1; type < CT_ALL; type = type << 1)
    2419              :                 {
    2420            0 :                         if (!(m_spAssTuner->constraint_type_enabled(type))) continue;
    2421            0 :                         for (size_t i = 0; i < m_vConstraint.size(); ++i)
    2422            0 :                                 if ((m_vConstraint[i]->type() & type) && m_vConstraint[i]->err_est_enabled())
    2423              :                                 {
    2424            0 :                                         m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    2425            0 :                                         m_vConstraint[i]->adjust_error(u, dd, type);
    2426              :                                 }
    2427              :                 }
    2428              :         }
    2429            0 :         UG_CATCH_THROW("Cannot adjust error assemblings.");
    2430              : 
    2431              : //      summarize the error estimator data in the discretizations
    2432              :         try
    2433              :         {
    2434            0 :                 for (std::size_t i = 0; i < vErrEstData.size(); ++i)
    2435            0 :                         vErrEstData[i]->summarize_err_est_data(m_spApproxSpace->domain());
    2436              :         }
    2437            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot summarize the error estimator");
    2438              : 
    2439              : // perform integrations for error estimators and mark elements
    2440              :         typedef typename domain_traits<dim>::element_type elem_type;
    2441              :         typedef typename SurfaceView::traits<elem_type>::const_iterator elem_iter_type;
    2442              : 
    2443            0 :         m_mgElemErrors.attach_indicators(pMG);
    2444              : 
    2445              :         // loop surface elements
    2446              :         ConstSmartPtr<SurfaceView> sv = dd->surface_view();
    2447              :         const GridLevel& gl = dd->grid_level();
    2448              :         elem_iter_type elem_iter_end = sv->template end<elem_type> (gl, SurfaceView::ALL);
    2449            0 :         for (elem_iter_type elem = sv->template begin<elem_type> (gl, SurfaceView::ALL); elem != elem_iter_end; ++elem)
    2450              :         {
    2451              :                 // clear attachment (to be on the safe side)
    2452            0 :                 m_mgElemErrors.error(*elem) = 0.0;
    2453              : 
    2454              :                 // get corner coordinates
    2455            0 :                 std::vector<MathVector<dim> > vCornerCoords = std::vector<MathVector<dim> >(0);
    2456            0 :                 CollectCornerCoordinates(vCornerCoords, *elem, m_spApproxSpace->domain()->position_accessor(), false);
    2457              : 
    2458              :                 // integrate for all estimators, then add up
    2459            0 :                 for (std::size_t ee = 0; ee < vErrEstData.size(); ++ee)
    2460            0 :                         m_mgElemErrors.error(*elem) += vErrEstData[ee]->scaling_factor()
    2461            0 :                                                                 * vErrEstData[ee]->get_elem_error_indicator(*elem, &vCornerCoords[0]);
    2462              :         }
    2463              : 
    2464              : //      write error estimator values to vtk
    2465            0 :         if (u_vtk)
    2466              :         {
    2467              :                 // local indices and solution
    2468              :                 LocalIndices ind; LocalVector locU;
    2469              : 
    2470              :                 // cast u_vtk to grid_function
    2471            0 :                 GridFunction<TDomain, CPUAlgebra>* uVTK = dynamic_cast<GridFunction<TDomain, CPUAlgebra>*>(u_vtk);
    2472            0 :                 if (!uVTK)
    2473              :                 {
    2474            0 :                         UG_THROW("Argument passed as output for error function is not a GridFunction of suitable type.");
    2475              :                 }
    2476              : 
    2477              :                 // clear previous values
    2478              :                 uVTK->set(0.0);
    2479              : 
    2480              :                 // map attachments to grid function
    2481            0 :                 ConstSmartPtr<SurfaceView> sv = uVTK->approx_space()->dof_distribution(gl)->surface_view();
    2482              :                 elem_iter_type elem_iter_end = sv->template end<elem_type> (gl, SurfaceView::ALL);
    2483            0 :                 for (elem_iter_type elem = sv->template begin<elem_type> (gl, SurfaceView::ALL); elem != elem_iter_end; ++elem)
    2484              :                 {
    2485              :                         //      get global indices
    2486            0 :                         uVTK->approx_space()->dof_distribution(gl)->indices(*elem, ind, false);
    2487              : 
    2488            0 :                         UG_COND_THROW(ind.num_fct() != 1,
    2489              :                                 "Number of functions in grid function passed for error indicator values is not 1 on "
    2490              :                                 << ElementDebugInfo(*uVTK->domain()->grid(), *elem) << ".");
    2491              : 
    2492            0 :                         UG_COND_THROW(ind.num_dof(0) != 1,
    2493              :                                 "Number of DoFs in grid function passed for error indicator values is not 1 on "
    2494              :                                 << ElementDebugInfo(*uVTK->domain()->grid(), *elem) << ".");
    2495              : 
    2496              :                         //      adapt local algebra
    2497            0 :                         locU.resize(ind);
    2498              : 
    2499              :                         //      read local values of u
    2500            0 :                         GetLocalVector(locU, *uVTK);
    2501              : 
    2502              :                         // assign error value
    2503            0 :                         locU(0,0) = m_mgElemErrors.error(*elem);
    2504              : 
    2505              :                         // add to grid function
    2506            0 :                         AddLocalVector(*uVTK, locU);
    2507              :                 }
    2508              :         }
    2509              : 
    2510            0 :         this->m_bErrorCalculated = true;
    2511              : 
    2512              : //      postprocess the error estimators in the discretizations
    2513              :         try{
    2514            0 :                 for(std::size_t i = 0; i < vErrEstData.size(); ++i)
    2515            0 :                         vErrEstData[i]->release_err_est_data();
    2516              :         }
    2517            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot release the error estimator");
    2518            0 : }
    2519              : 
    2520              : /**
    2521              :  * This function assembles the error estimator associated with all the
    2522              :  * element discretizations in the internal data structure for one given subset.
    2523              :  *
    2524              :  * \param[in]           vElemDisc               element discretizations
    2525              :  * \param[in]           dd                              DoF Distribution
    2526              :  * \param[in]           si                              subset index
    2527              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2528              :  * \param[in]           u                               solution
    2529              :  */
    2530              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2531              : template <typename TElem>
    2532            0 : inline void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2533              : AssembleErrorEstimator( const std::vector<IElemError<domain_type>*>& vElemDisc,
    2534              :                                                 ConstSmartPtr<DoFDistribution> dd,
    2535              :                                                 int si, bool bNonRegularGrid,
    2536              :                                                 const vector_type& u)
    2537              : {
    2538              :         //      general case: assembling over all elements in subset si
    2539              :         gass_type::template AssembleErrorEstimator<TElem>
    2540            0 :                 (vElemDisc, m_spApproxSpace->domain(), dd,
    2541              :                         dd->template begin<TElem>(si), dd->template end<TElem>(si),
    2542              :                                 si, bNonRegularGrid, u);
    2543            0 : }
    2544              : 
    2545              : ///////////////////////////////////////////////////////////////////////////////
    2546              : // Error estimator (instationary)
    2547              : ///////////////////////////////////////////////////////////////////////////////
    2548              : 
    2549              : 
    2550              : 
    2551              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2552            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2553              : calc_error(ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    2554              :                    ConstSmartPtr<DoFDistribution> dd,
    2555              :                    const std::vector<number>& vScaleMass,
    2556              :                    const std::vector<number>& vScaleStiff,
    2557              :                    error_vector_type* u_vtk)
    2558              : {
    2559              :         PROFILE_FUNC_GROUP("error_estimator");
    2560              : 
    2561              : //      get multigrid
    2562              :         SmartPtr<MultiGrid> pMG = ((DoFDistribution *) dd.get())->multi_grid();
    2563              : 
    2564              : // check, whether separate error data exists
    2565              :         const bool useErrorData = !m_vDomainElemError.empty();
    2566              : 
    2567              : //      update elem items
    2568            0 :         if (useErrorData) { update_error_items();}
    2569              :         else { update_disc_items();}
    2570              : 
    2571              : //      Union of Subsets
    2572            0 :         SubsetGroup unionSubsets;
    2573              :         std::vector<SubsetGroup> vSSGrp;
    2574              : 
    2575              : //      create list of all subsets
    2576              :         try
    2577              :         {
    2578            0 :                 if (useErrorData) {CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemError, dd->subset_handler());}
    2579            0 :                 else {CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());}
    2580              :         }
    2581            0 :         UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    2582              : 
    2583              : //      collect the error estimator data (for all discretizations)
    2584              :         std::vector<IErrEstData<TDomain>*> vErrEstData;
    2585              : 
    2586            0 :         if (useErrorData) CollectIErrEstData(vErrEstData, m_vElemError);
    2587            0 :         else CollectIErrEstData(vErrEstData, m_vElemDisc);
    2588              : 
    2589              : //      preprocess the error estimator data in the discretizations
    2590              :         try
    2591              :         {
    2592            0 :                 for (std::size_t i = 0; i < vErrEstData.size(); ++i)
    2593            0 :                         vErrEstData[i]->alloc_err_est_data(dd->surface_view(), dd->grid_level());
    2594              :         }
    2595            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot prepare the error estimator");
    2596              : 
    2597              : //      loop subsets to assemble the estimators
    2598            0 :         for (std::size_t i = 0; i < unionSubsets.size(); ++i)
    2599              :         {
    2600              :         //      get subset
    2601              :                 const int si = unionSubsets[i];
    2602              : 
    2603              :         //      get dimension of the subset
    2604            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    2605              : 
    2606              :         //      request if subset is regular grid
    2607            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    2608              : 
    2609              :         //      collect all element discretizations that work on the subset
    2610              :                 typedef std::vector<IElemError<TDomain>*> error_vector_type;
    2611              :                 error_vector_type vSubsetElemError;
    2612              : 
    2613            0 :                 if (useErrorData) {
    2614              :                          GetElemDiscItemOnSubset<IElemError<TDomain>, IElemError<TDomain> >
    2615            0 :                                                         (vSubsetElemError, m_vElemError, vSSGrp, si);
    2616              :                 }
    2617              :                 else
    2618              :                 {
    2619              :                          GetElemDiscItemOnSubset<IElemError<TDomain>, IElemDisc<TDomain> >
    2620            0 :                                                                                 (vSubsetElemError, m_vElemDisc, vSSGrp, si);
    2621              :                 }
    2622              : 
    2623              :         //      remove from elemDisc list those with !err_est_enabled()
    2624              :                 typename error_vector_type::iterator it = vSubsetElemError.begin();
    2625            0 :                 while (it != vSubsetElemError.end())
    2626              :                 {
    2627            0 :                         if (!(*it)->err_est_enabled())
    2628              :                                 it = vSubsetElemError.erase(it);
    2629              :                         else ++it;
    2630              :                 }
    2631              : 
    2632              :         //      assemble on suitable elements
    2633              :                 try
    2634              :                 {
    2635            0 :                         switch (dim)
    2636              :                         {
    2637              :                         case 1:
    2638              :                                 this->template AssembleErrorEstimator<RegularEdge>
    2639            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2640              :                                 // When assembling over lower-dim manifolds that contain hanging nodes:
    2641              :                                 this->template AssembleErrorEstimator<ConstrainingEdge>
    2642            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2643            0 :                                 break;
    2644              :                         case 2:
    2645              :                                 this->template AssembleErrorEstimator<Triangle>
    2646            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2647              :                                 this->template AssembleErrorEstimator<Quadrilateral>
    2648            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2649              :                                 // When assembling over lower-dim manifolds that contain hanging nodes:
    2650              :                                 this->template AssembleErrorEstimator<ConstrainingTriangle>
    2651            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2652              :                                 this->template AssembleErrorEstimator<ConstrainingQuadrilateral>
    2653            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2654            0 :                                 break;
    2655              :                         case 3:
    2656              :                                 this->template AssembleErrorEstimator<Tetrahedron>
    2657            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2658              :                                 this->template AssembleErrorEstimator<Pyramid>
    2659            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2660              :                                 this->template AssembleErrorEstimator<Prism>
    2661            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2662              :                                 this->template AssembleErrorEstimator<Hexahedron>
    2663            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2664              :                                 this->template AssembleErrorEstimator<Octahedron>
    2665            0 :                                         (vSubsetElemError, dd, si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2666            0 :                                 break;
    2667            0 :                         default:
    2668            0 :                                 UG_THROW("DomainDiscretization::calc_error:"
    2669              :                                                                 " Dimension "<<dim<<" (subset="<<si<<") not supported.");
    2670              :                         }
    2671              :                 }
    2672            0 :                 UG_CATCH_THROW("DomainDiscretization::calc_error:"
    2673              :                                                 " Assembling of elements of Dimension " << dim << " in "
    2674              :                                                 " subset "<< si << "failed.");
    2675              :         }
    2676              : 
    2677              : //      apply constraints
    2678              :         try
    2679              :         {
    2680            0 :                 for (int type = 1; type < CT_ALL; type = type << 1)
    2681              :                 {
    2682            0 :                         if (!(m_spAssTuner->constraint_type_enabled(type))) continue;
    2683            0 :                         for (size_t i = 0; i < m_vConstraint.size(); ++i)
    2684            0 :                                 if ((m_vConstraint[i]->type() & type) && m_vConstraint[i]->err_est_enabled())
    2685              :                                 {
    2686            0 :                                         m_vConstraint[i]->set_ass_tuner(m_spAssTuner);
    2687            0 :                                         m_vConstraint[i]->adjust_error(*vSol->solution(0), dd, type, vSol->time(0),
    2688              :                                                 vSol, &vScaleMass, &vScaleStiff);
    2689              :                                 }
    2690              :                 }
    2691              :         }
    2692            0 :         UG_CATCH_THROW("Cannot adjust error assemblings.");
    2693              : 
    2694              : //      summarize the error estimator data in the discretizations
    2695              :         try
    2696              :         {
    2697            0 :                 for (std::size_t i = 0; i < vErrEstData.size(); ++i)
    2698            0 :                         vErrEstData[i]->summarize_err_est_data(m_spApproxSpace->domain());
    2699              :         }
    2700            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot summarize the error estimator.");
    2701              : 
    2702              :         // perform integrations for error estimators and mark elements
    2703              :         typedef typename domain_traits<dim>::element_type elem_type;
    2704              :         typedef typename SurfaceView::traits<elem_type>::const_iterator elem_iter_type;
    2705              : 
    2706            0 :         m_mgElemErrors.attach_indicators(pMG);
    2707              : 
    2708              :         // loop surface elements
    2709              :         ConstSmartPtr<SurfaceView> sv = dd->surface_view();
    2710              :         const GridLevel& gl = dd->grid_level();
    2711              :         elem_iter_type elem_iter_end = sv->template end<elem_type> (gl, SurfaceView::ALL);
    2712            0 :         for (elem_iter_type elem = sv->template begin<elem_type> (gl, SurfaceView::ALL); elem != elem_iter_end; ++elem)
    2713              :         {
    2714              :                 // clear attachment
    2715            0 :                 m_mgElemErrors.error(*elem) = 0.0;
    2716              : 
    2717              :                 // get corner coordinates
    2718            0 :                 std::vector<MathVector<dim> > vCornerCoords = std::vector<MathVector<dim> >(0);
    2719            0 :                 CollectCornerCoordinates(vCornerCoords, *elem, m_spApproxSpace->domain()->position_accessor(), false);
    2720              : 
    2721              :                 // integrate for all estimators, then add up
    2722            0 :                 for (std::size_t ee = 0; ee < vErrEstData.size(); ++ee)
    2723            0 :                         m_mgElemErrors.error(*elem) += vErrEstData[ee]->scaling_factor()
    2724            0 :                                                                 * vErrEstData[ee]->get_elem_error_indicator(*elem, &vCornerCoords[0]);
    2725              :         }
    2726              : 
    2727              : //      write error estimator values to vtk
    2728            0 :         if (u_vtk)
    2729              :         {
    2730              :                 // local indices and solution
    2731              :                 LocalIndices ind; LocalVector locU;
    2732              : 
    2733              :                 // cast u_vtk to grid_function
    2734            0 :                 GridFunction<TDomain,TAlgebra>* uVTK = dynamic_cast<GridFunction<TDomain,TAlgebra>*>(u_vtk);
    2735            0 :                 if (!uVTK)
    2736              :                 {
    2737            0 :                         UG_THROW("Argument passed as output for error function is not a GridFunction.");
    2738              :                 }
    2739              : 
    2740              :                 // clear previous values
    2741              :                 uVTK->set(0.0);
    2742              : 
    2743              :                 // map attachments to grid function
    2744            0 :                 ConstSmartPtr<SurfaceView> sv = uVTK->approx_space()->dof_distribution(gl)->surface_view();
    2745              :                 elem_iter_type elem_iter_end = sv->template end<elem_type> (gl, SurfaceView::ALL);
    2746            0 :                 for (elem_iter_type elem = sv->template begin<elem_type> (gl, SurfaceView::ALL); elem != elem_iter_end; ++elem)
    2747              :                 {
    2748              :                         //      get global indices
    2749            0 :                         uVTK->approx_space()->dof_distribution(gl)->indices(*elem, ind, false);
    2750              : 
    2751              :                         //      adapt local algebra
    2752            0 :                         locU.resize(ind);
    2753              : 
    2754              :                         //      read local values of u
    2755            0 :                         GetLocalVector(locU, *uVTK);
    2756              : 
    2757              :                         // assign error value
    2758            0 :                         locU(0,0) = m_mgElemErrors.error(*elem);
    2759              : 
    2760              :                         // add to grid function
    2761            0 :                         AddLocalVector(*uVTK, locU);
    2762              :                 }
    2763              :         }
    2764              : 
    2765            0 :         this->m_bErrorCalculated = true;
    2766              : 
    2767              : //      postprocess the error estimators in the discretizations
    2768              :         try{
    2769            0 :                 for(std::size_t i = 0; i < vErrEstData.size(); ++i)
    2770            0 :                         vErrEstData[i]->release_err_est_data();
    2771              :         }
    2772            0 :         UG_CATCH_THROW("DomainDiscretization::calc_error: Cannot release the error estimator");
    2773            0 : }
    2774              : 
    2775              : /**
    2776              :  * This function assembles the error estimator associated with all the
    2777              :  * element discretizations in the internal data structure for one given subset.
    2778              :  *
    2779              :  * \param[in]           vElemDisc               element discretizations
    2780              :  * \param[in]           dd                              DoF Distribution
    2781              :  * \param[in]           si                              subset index
    2782              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2783              :  * \param[in]           vScaleMass              scaling factors for mass part
    2784              :  * \param[in]           vScaleStiff             scaling factors for stiffness part
    2785              :  * \param[in]           vSol                            solution
    2786              :  */
    2787              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2788              : template <typename TElem>
    2789            0 : inline void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2790              : AssembleErrorEstimator( const std::vector<IElemError<domain_type>*>& vElemDisc,
    2791              :                                                 ConstSmartPtr<DoFDistribution> dd,
    2792              :                                                 int si, bool bNonRegularGrid,
    2793              :                                                 const std::vector<number>& vScaleMass,
    2794              :                                                 const std::vector<number>& vScaleStiff,
    2795              :                                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol)
    2796              : {
    2797              :         //      general case: assembling over all elements in subset si
    2798              :         gass_type::template AssembleErrorEstimator<TElem>
    2799            0 :                 (vElemDisc, m_spApproxSpace->domain(), dd,
    2800              :                         dd->template begin<TElem>(si), dd->template end<TElem>(si),
    2801              :                                 si, bNonRegularGrid, vScaleMass, vScaleStiff, vSol);
    2802            0 : }
    2803              : 
    2804              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2805            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2806              : mark_with_strategy
    2807              : (       IRefiner& refiner,
    2808              :         SmartPtr<IElementMarkingStrategy<TDomain> >spMarkingStrategy
    2809              : )
    2810              : {
    2811              :         // check that error indicators have been calculated
    2812            0 :         if (!this->m_bErrorCalculated)
    2813              :         {
    2814            0 :                 UG_THROW("Error indicators have to be calculated first by a call to 'calc_error'.");
    2815              :         }
    2816              : 
    2817              :         // mark elements for refinement
    2818            0 :         if (spMarkingStrategy.valid())
    2819              :         {
    2820            0 :                 spMarkingStrategy->mark( m_mgElemErrors, refiner, this->dd(GridLevel(GridLevel::TOP, GridLevel::SURFACE)));
    2821              :         }
    2822            0 : }
    2823              : 
    2824              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2825            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2826              : invalidate_error()
    2827              : {
    2828              :         typedef typename domain_traits<dim>::element_type elem_type;
    2829              : 
    2830              :         // check that error indicators have been calculated
    2831            0 :         if (m_bErrorCalculated)
    2832              :         {
    2833            0 :                 m_bErrorCalculated = false;
    2834            0 :                 m_mgElemErrors.detach_indicators();
    2835              :                 // this->m_pMG->template detach_from<elem_type>(this->m_aError);
    2836              :         }
    2837            0 : }
    2838              : 
    2839              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2840            0 : bool DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2841              : is_error_valid()
    2842              : {
    2843              :         // check that error indicators have been calculated
    2844            0 :         return this->m_bErrorCalculated;
    2845              : }
    2846              : 
    2847              : ///////////////////////////////////////////////////////////////////////////////
    2848              : // Finish Timestep (instationary)
    2849              : ///////////////////////////////////////////////////////////////////////////////
    2850              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2851            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2852              : finish_timestep
    2853              : (
    2854              :         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    2855              :         ConstSmartPtr<DoFDistribution> dd
    2856              : )
    2857              : {
    2858              :         PROFILE_FUNC_GROUP("discretization");
    2859              : //      update the elem discs
    2860              :         update_disc_items();
    2861            0 :         prep_assemble_loop(m_vElemDisc);
    2862              : 
    2863              : //      find out whether grid is regular
    2864              :         ConstSmartPtr<ISubsetHandler> sh = dd->subset_handler();
    2865            0 :         size_t num_subsets = sh->num_subsets();
    2866              :         bool bNonRegularGrid = false;
    2867            0 :         for (size_t si = 0; si < num_subsets; ++si)
    2868            0 :                 bNonRegularGrid |= !SubsetIsRegularGrid(*sh, si);
    2869              : 
    2870              : //      overrule by regular grid if required
    2871            0 :         if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    2872              : 
    2873              : //      call assembler's FinishTimestep
    2874              :         try
    2875              :         {
    2876            0 :                 gass_type::FinishTimestep(m_vElemDisc, dd, bNonRegularGrid, vSol, m_spAssTuner);
    2877              :         }
    2878            0 :         UG_CATCH_THROW("DomainDiscretization::finish_timestep (instationary):" <<
    2879              :                                    " Finishing time step failed.");
    2880              : 
    2881            0 :         post_assemble_loop(m_vElemDisc);
    2882            0 : }
    2883              : 
    2884              : ///////////////////////////////////////////////////////////////////////////////
    2885              : // Finish Timestep Elem (instationary)
    2886              : ///////////////////////////////////////////////////////////////////////////////
    2887              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2888            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2889              : finish_timestep_elem(ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    2890              :                 ConstSmartPtr<DoFDistribution> dd)
    2891              : {
    2892              :         PROFILE_FUNC_GROUP("discretization");
    2893              : //      update the elem discs
    2894              :         update_disc_items();
    2895              : 
    2896              : //      Union of Subsets
    2897            0 :         SubsetGroup unionSubsets;
    2898              :         std::vector<SubsetGroup> vSSGrp;
    2899              : 
    2900              : //      create list of all subsets
    2901              :         try{
    2902            0 :                 CreateSubsetGroups(vSSGrp, unionSubsets, m_vElemDisc, dd->subset_handler());
    2903            0 :         }UG_CATCH_THROW("'DomainDiscretization': Can not create Subset Groups and Union.");
    2904              : 
    2905              : //      loop subsets
    2906            0 :         for(size_t i = 0; i < unionSubsets.size(); ++i)
    2907              :         {
    2908              :         //      get subset
    2909              :                 const int si = unionSubsets[i];
    2910              : 
    2911              :         //      get dimension of the subset
    2912            0 :                 const int dim = DimensionOfSubset(*dd->subset_handler(), si);
    2913              : 
    2914              :         //      request if subset is regular grid
    2915            0 :                 bool bNonRegularGrid = !unionSubsets.regular_grid(i);
    2916              : 
    2917              :         //      overrule by regular grid if required
    2918            0 :                 if(m_spAssTuner->regular_grid_forced()) bNonRegularGrid = false;
    2919              : 
    2920              :         //      Elem Disc on the subset
    2921              :                 std::vector<IElemDisc<TDomain>*> vSubsetElemDisc;
    2922              : 
    2923              :         //      get all element discretizations that work on the subset
    2924            0 :                 GetElemDiscOnSubset(vSubsetElemDisc, m_vElemDisc, vSSGrp, si);
    2925              : 
    2926              :         //      assemble on suitable elements
    2927              :                 try
    2928              :                 {
    2929            0 :                 switch(dim)
    2930              :                 {
    2931              :                 case 0:
    2932              :                         this->template FinishTimestepElem<RegularVertex>
    2933            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2934            0 :                         break;
    2935              :                 case 1:
    2936              :                         this->template FinishTimestepElem<RegularEdge>
    2937            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2938              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    2939              :                         this->template FinishTimestepElem<ConstrainingEdge>
    2940            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2941            0 :                         break;
    2942              :                 case 2:
    2943              :                         this->template FinishTimestepElem<Triangle>
    2944            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2945              :                         this->template FinishTimestepElem<Quadrilateral>
    2946            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2947              :                         // When assembling over lower-dim manifolds that contain hanging nodes:
    2948              :                         this->template FinishTimestepElem<ConstrainingTriangle>
    2949            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2950              :                         this->template FinishTimestepElem<ConstrainingQuadrilateral>
    2951            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2952            0 :                         break;
    2953              :                 case 3:
    2954              :                         this->template FinishTimestepElem<Tetrahedron>
    2955            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2956              :                         this->template FinishTimestepElem<Pyramid>
    2957            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2958              :                         this->template FinishTimestepElem<Prism>
    2959            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2960              :                         this->template FinishTimestepElem<Hexahedron>
    2961            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2962              :                         this->template FinishTimestepElem<Octahedron>
    2963            0 :                                 (vSubsetElemDisc, dd, si, bNonRegularGrid, vSol);
    2964            0 :                         break;
    2965            0 :                 default:
    2966            0 :                         UG_THROW("DomainDiscretization::finish_timestep_elem (instationary):"
    2967              :                                                         "Dimension "<<dim<<" (subset="<<si<<") not supported.");
    2968              :                 }
    2969              :                 }
    2970            0 :                 UG_CATCH_THROW("DomainDiscretization::finish_timestep_elem (instationary):"
    2971              :                                                 " Assembling of elements of Dimension " << dim << " in "
    2972              :                                                 " subset "<<si<< " failed.");
    2973              :         }
    2974              : 
    2975            0 : }
    2976              : 
    2977              : /**
    2978              :  * This function finalizes the global discretization in a time-stepping scheme
    2979              :  * by calling the "finish_timestep_elem" methods of all passed element
    2980              :  * discretizations on one given subset.
    2981              :  *
    2982              :  * \param[in]           vElemDisc               element discretizations
    2983              :  * \param[in]           dd                              DoF Distribution
    2984              :  * \param[in]           si                              subset index
    2985              :  * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2986              :  * \param[in]           vSol                    current and previous solutions
    2987              :  */
    2988              : template <typename TDomain, typename TAlgebra, typename TGlobAssembler>
    2989              : template <typename TElem>
    2990            0 : void DomainDiscretizationBase<TDomain, TAlgebra, TGlobAssembler>::
    2991              : FinishTimestepElem(const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    2992              :                            ConstSmartPtr<DoFDistribution> dd,
    2993              :                            int si, bool bNonRegularGrid,
    2994              :                            ConstSmartPtr<VectorTimeSeries<vector_type> > vSol)
    2995              : {
    2996              :         //      check if only some elements are selected
    2997            0 :         if(m_spAssTuner->selected_elements_used())
    2998              :         {
    2999              :                 std::vector<TElem*> vElem;
    3000            0 :                 m_spAssTuner->collect_selected_elements(vElem, dd, si);
    3001              : 
    3002              :                 //      assembling is carried out only over those elements
    3003              :                 //      which are selected and in subset si
    3004              :                 gass_type::template FinishTimestepElem<TElem>
    3005            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd, vElem.begin(), vElem.end(), si,
    3006              :                          bNonRegularGrid, vSol, m_spAssTuner);
    3007            0 :         }
    3008              :         else
    3009              :         {
    3010              :                 //      general case: assembling over all elements in subset si
    3011              :                 gass_type::template FinishTimestepElem<TElem>
    3012            0 :                         (vElemDisc, m_spApproxSpace->domain(), dd,
    3013              :                                 dd->template begin<TElem>(si), dd->template end<TElem>(si), si,
    3014              :                                         bNonRegularGrid, vSol, m_spAssTuner);
    3015              :         }
    3016            0 : }
    3017              : 
    3018              : } // end namespace ug
    3019              : 
    3020              : #endif /*__H__UG__LIB_DISC__SPATIAL_DISC__DOMAIN_DISC_IMPL__*/
        

Generated by: LCOV version 2.0-1