LCOV - code coverage report
Current view: top level - ugbase/lib_disc/spatial_disc/elem_disc - elem_disc_assemble_util.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 462 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 3024 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__ELEM_DISC__ELEM_DISC_ASSEMBLE_UTIL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__ELEM_DISC__ELEM_DISC_ASSEMBLE_UTIL__
      35              : 
      36              : // extern includes
      37              : #include <iostream>
      38              : #include <vector>
      39              : 
      40              : // other ug4 modules
      41              : #include "common/common.h"
      42              : 
      43              : // intern headers
      44              : #include "../../reference_element/reference_element.h"
      45              : #include "./elem_disc_interface.h"
      46              : #include "lib_disc/common/function_group.h"
      47              : #include "lib_disc/common/local_algebra.h"
      48              : #include "lib_disc/spatial_disc/user_data/data_evaluator.h"
      49              : #include "bridge/util_algebra_dependent.h"
      50              : 
      51              : #define PROFILE_ELEM_LOOP
      52              : #ifdef PROFILE_ELEM_LOOP
      53              :         #define EL_PROFILE_FUNC()               PROFILE_FUNC()
      54              :         #define EL_PROFILE_BEGIN(name)  PROFILE_BEGIN(name)
      55              :         #define EL_PROFILE_END()                PROFILE_END()
      56              : #else
      57              :         #define EL_PROFILE_FUNC()
      58              :         #define EL_PROFILE_BEGIN(name)
      59              :         #define EL_PROFILE_END()
      60              : #endif
      61              : 
      62              : 
      63              : namespace ug {
      64              : 
      65              : extern DebugID DID_ELEM_DISC_ASSEMBLE_UTIL;
      66              : 
      67              : /// Global assembler based on the straightforward application of the local discretizations
      68              : /**
      69              :  * Template class of the global assembler that applyes the local (element)
      70              :  * discretizations to the elements in given subsets and adds the local data
      71              :  * to the global ones.
      72              :  *
      73              :  * \tparam TDomain              domain type
      74              :  * \tparam TAlgebra             algebra type
      75              :  */
      76              : template <typename TDomain, typename TAlgebra>
      77              : class StdGlobAssembler
      78              : {
      79              :         ///     Domain type
      80              :         typedef TDomain domain_type;
      81              :         
      82              :         ///     Algebra type
      83              :         typedef TAlgebra algebra_type;
      84              :         
      85              :         ///     Vector type in the algebra
      86              :         typedef typename algebra_type::vector_type vector_type;
      87              :         
      88              :         ///     Matrix type in the algebra
      89              :         typedef typename algebra_type::matrix_type matrix_type;
      90              :         
      91              : ////////////////////////////////////////////////////////////////////////////////
      92              : // Assemble Stiffness Matrix
      93              : ////////////////////////////////////////////////////////////////////////////////
      94              : 
      95              : public:
      96              :         /**
      97              :          * This function adds the contributions of all passed element discretizations
      98              :          * on one given subset to the global Stiffness matrix. (This version
      99              :          * processes elements in a given interval.)
     100              :          *
     101              :          * \param[in]           vElemDisc               element discretizations
     102              :          * \param[in]           spDomain                domain
     103              :          * \param[in]           dd                              DoF Distribution
     104              :          * \param[in]           iterBegin               element iterator
     105              :          * \param[in]           iterEnd                 element iterator
     106              :          * \param[in]           si                              subset index
     107              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     108              :          * \param[in,out]       A                               Stiffness matrix
     109              :          * \param[in]           u                               solution
     110              :          * \param[in]           spAssTuner              assemble adapter
     111              :          */
     112              :         template <typename TElem, typename TIterator>
     113              :         static void
     114            0 :         AssembleStiffnessMatrix(        const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     115              :                                                                 ConstSmartPtr<domain_type> spDomain,
     116              :                                                                 ConstSmartPtr<DoFDistribution> dd,
     117              :                                                                 TIterator iterBegin,
     118              :                                                                 TIterator iterEnd,
     119              :                                                                 int si, bool bNonRegularGrid,
     120              :                                                                 matrix_type& A,
     121              :                                                                 const vector_type& u,
     122              :                                                                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     123              :         {
     124              :         //      check if there are any elements at all, otherwise return immediately
     125            0 :                 if(iterBegin == iterEnd) return;
     126              : 
     127              :         //      reference object id
     128              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     129              : 
     130              :         //      storage for corner coordinates
     131            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     132              : 
     133              :                 try
     134              :                 {
     135            0 :                 DataEvaluator<domain_type> Eval(STIFF,
     136              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
     137              : 
     138              :         //      prepare element loop
     139            0 :                 Eval.prepare_elem_loop(id, si);
     140              : 
     141              :         //      local indices and local algebra
     142              :                 LocalIndices ind; LocalVector locU; LocalMatrix locA;
     143              : 
     144              :         //      Loop over all elements
     145            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     146              :                 {
     147              :                 //      get Element
     148            0 :                         TElem* elem = *iter;
     149              : 
     150              :                 //      get corner coordinates
     151            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     152              : 
     153              :                 //      check if elem is skipped from assembling
     154            0 :                         if(!spAssTuner->element_used(elem)) continue;
     155              : 
     156              :                 //      get global indices
     157            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     158              : 
     159              :                 //      adapt local algebra
     160            0 :                         locU.resize(ind); locA.resize(ind);
     161              : 
     162              :                 //      read local values of u
     163            0 :                         GetLocalVector(locU, u);
     164              : 
     165              :                 //      prepare element
     166              :                         try
     167              :                         {
     168            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, true);
     169              :                         }
     170            0 :                         UG_CATCH_THROW("AssembleStiffnessMatrix Cannot prepare element.");
     171              : 
     172              :                 //      Assemble JA
     173            0 :                         locA = 0.0;
     174              :                         try
     175              :                         {
     176            0 :                                 Eval.add_jac_A_elem(locA, locU, elem, vCornerCoords);
     177              :                         }
     178            0 :                         UG_CATCH_THROW("AssembleStiffnessMatrix: Cannot compute Jacobian (A).");
     179              : 
     180              :                 //      send local to global matrix
     181              :                         try{
     182            0 :                                 spAssTuner->add_local_mat_to_global(A,locA,dd);
     183              :                         }
     184            0 :                         UG_CATCH_THROW("AssembleStiffnessMatrix: Cannot add local matrix.");
     185              :                 }
     186              : 
     187              :         //      finish element loop
     188              :                 try
     189              :                 {
     190            0 :                         Eval.finish_elem_loop();
     191              :                 }
     192            0 :                 UG_CATCH_THROW("AssembleStiffnessMatrix: Cannot finish element loop.");
     193              : 
     194            0 :                 }
     195            0 :                 UG_CATCH_THROW("AssembleStiffnessMatrix': Cannot create Data Evaluator.");
     196              :         }
     197              : 
     198              : ////////////////////////////////////////////////////////////////////////////////
     199              : // Assemble Mass Matrix
     200              : ////////////////////////////////////////////////////////////////////////////////
     201              : 
     202              : public:
     203              :         /**
     204              :          * This function adds the contributions of all passed element discretizations
     205              :          * on one given subset to the global Mass matrix. (This version
     206              :          * processes elements in a given interval.)
     207              :          *
     208              :          * \param[in]           vElemDisc               element discretizations
     209              :          * \param[in]           spDomain                domain
     210              :          * \param[in]           dd                              DoF Distribution
     211              :          * \param[in]           iterBegin               element iterator
     212              :          * \param[in]           iterEnd                 element iterator
     213              :          * \param[in]           si                              subset index
     214              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     215              :          * \param[in,out]       M                               Mass matrix
     216              :          * \param[in]           u                               solution
     217              :          * \param[in]           spAssTuner              assemble adapter
     218              :          */
     219              :         template <typename TElem, typename TIterator>
     220              :         static void
     221            0 :         AssembleMassMatrix( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     222              :                                                 ConstSmartPtr<domain_type> spDomain,
     223              :                                                 ConstSmartPtr<DoFDistribution> dd,
     224              :                                                 TIterator iterBegin,
     225              :                                                 TIterator iterEnd,
     226              :                                                 int si, bool bNonRegularGrid,
     227              :                                                 matrix_type& M,
     228              :                                                 const vector_type& u,
     229              :                                                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     230              :         {
     231              :         //      check if there are any elements at all, otherwise return immediately
     232            0 :                 if(iterBegin == iterEnd) return;
     233              : 
     234              :         //      reference object id
     235              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     236              : 
     237              :         //      storage for corner coordinates
     238            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     239              : 
     240              :         //      prepare for given elem discs
     241              :                 try
     242              :                 {
     243            0 :                 DataEvaluator<domain_type> Eval(MASS,
     244              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
     245              : 
     246              :         //      prepare element loop
     247            0 :                 Eval.prepare_elem_loop(id, si);
     248              : 
     249              :         //      local indices and local algebra
     250              :                 LocalIndices ind; LocalVector locU; LocalMatrix locM;
     251              : 
     252              :         //      Loop over all elements
     253            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     254              :                 {
     255              :                 //      get Element
     256            0 :                         TElem* elem = *iter;
     257              : 
     258              :                 //      get corner coordinates
     259            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     260              : 
     261              :                 //      check if elem is skipped from assembling
     262            0 :                         if(!spAssTuner->element_used(elem)) continue;
     263              : 
     264              :                 //      get global indices
     265            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     266              : 
     267              :                 //      adapt local algebra
     268            0 :                         locU.resize(ind); locM.resize(ind);
     269              : 
     270              :                 //      read local values of u
     271            0 :                         GetLocalVector(locU, u);
     272              : 
     273              :                 //      prepare element
     274              :                         try
     275              :                         {
     276            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, true);
     277              :                         }
     278            0 :                         UG_CATCH_THROW("AssembleMassMatrix: Cannot prepare element.");
     279              : 
     280              :                 //      Assemble JM
     281            0 :                         locM = 0.0;
     282              :                         try
     283              :                         {
     284            0 :                                 Eval.add_jac_M_elem(locM, locU, elem, vCornerCoords);
     285              :                         }
     286            0 :                         UG_CATCH_THROW("AssembleMassMatrix: Cannot compute Jacobian (M).");
     287              : 
     288              :                 // send local to global matrix
     289              :                         try{
     290            0 :                                 spAssTuner->add_local_mat_to_global(M, locM, dd);
     291              :                         }
     292            0 :                         UG_CATCH_THROW("AssembleMassMatrix: Cannot add local matrix.");
     293              :                 }
     294              : 
     295              :         //      finish element loop
     296              :                 try
     297              :                 {
     298            0 :                         Eval.finish_elem_loop();
     299              :                 }
     300            0 :                 UG_CATCH_THROW("AssembleMassMatrix: Cannot finish element loop.");
     301              : 
     302            0 :                 }
     303            0 :                 UG_CATCH_THROW("AssembleMassMatrix: Cannot create Data Evaluator.");
     304              :         }
     305              : 
     306              : ////////////////////////////////////////////////////////////////////////////////
     307              : // Assemble (stationary) Jacobian
     308              : ////////////////////////////////////////////////////////////////////////////////
     309              : 
     310              : public:
     311              :         /**
     312              :          * This function adds the contributions of all passed element discretizations
     313              :          * on one given subset to the global Jacobian in the stationary case. (This version
     314              :          * processes elements in a given interval.)
     315              :          *
     316              :          * \param[in]           vElemDisc               element discretizations
     317              :          * \param[in]           spDomain                domain
     318              :          * \param[in]           iterBegin               element iterator
     319              :          * \param[in]           iterEnd                 element iterator
     320              :          * \param[in]           si                              subset index
     321              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     322              :          * \param[in,out]       J                               jacobian
     323              :          * \param[in]           u                               solution
     324              :          * \param[in]           spAssTuner              assemble adapter
     325              :          */
     326              :         template <typename TElem, typename TIterator>
     327              :         static void
     328            0 :         AssembleJacobian(       const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     329              :                                                 ConstSmartPtr<domain_type> spDomain,
     330              :                                                 ConstSmartPtr<DoFDistribution> dd,
     331              :                                                 TIterator iterBegin,
     332              :                                                 TIterator iterEnd,
     333              :                                                 int si, bool bNonRegularGrid,
     334              :                                                 matrix_type& J,
     335              :                                                 const vector_type& u,
     336              :                                                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     337              :         {
     338              :         //      check if there are any elements at all, otherwise return immediately
     339            0 :                 if(iterBegin == iterEnd) return;
     340              : 
     341              :         //      reference object id
     342              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     343              : 
     344              :         //      storage for corner coordinates
     345            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     346              : 
     347              :         //      prepare for given elem discs
     348              :                 try
     349              :                 {
     350            0 :                 DataEvaluator<domain_type> Eval(STIFF | RHS,
     351              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
     352              : 
     353              :         //      prepare element loop
     354            0 :                 Eval.prepare_elem_loop(id, si);
     355              : 
     356              :         //      local indices and local algebra
     357              :                 LocalIndices ind; LocalVector locU; LocalMatrix locJ;
     358              : 
     359              :         //      Loop over all elements
     360            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     361              :                 {
     362              :                 //      get Element
     363            0 :                         TElem* elem = *iter;
     364              : 
     365              :                 //      get corner coordinates
     366            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     367              : 
     368              :                 //      check if elem is skipped from assembling
     369            0 :                         if(!spAssTuner->element_used(elem)) continue;
     370              : 
     371              :                 //      get global indices
     372            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     373              : 
     374              :                 //      adapt local algebra
     375            0 :                         locU.resize(ind); locJ.resize(ind);
     376              : 
     377              :                 //      read local values of u
     378            0 :                         GetLocalVector(locU, u);
     379              : 
     380              :                 //      prepare element
     381              :                         try
     382              :                         {
     383            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, true);
     384              :                         }
     385            0 :                         UG_CATCH_THROW("(stationary) AssembleJacobian: Cannot prepare element.");
     386              : 
     387              :                 //      reset local algebra
     388            0 :                         locJ = 0.0;
     389              : 
     390              :                 //      Assemble JA
     391              :                         try
     392              :                         {
     393            0 :                                 Eval.add_jac_A_elem(locJ, locU, elem, vCornerCoords);
     394              :                         }
     395            0 :                         UG_CATCH_THROW("(stationary) AssembleJacobian: Cannot compute Jacobian (A).");
     396              : 
     397              :                 // send local to global matrix
     398              :                         try{
     399            0 :                                 spAssTuner->add_local_mat_to_global(J, locJ, dd);
     400              :                         }
     401            0 :                         UG_CATCH_THROW("(stationary) AssembleJacobian: Cannot add local matrix.");
     402              :                 }
     403              : 
     404              :         //      finish element loop
     405              :                 try
     406              :                 {
     407            0 :                         Eval.finish_elem_loop();
     408              :                 }
     409            0 :                 UG_CATCH_THROW("(stationary) AssembleJacobian: Cannot finish element loop.");
     410              : 
     411            0 :                 }
     412            0 :                 UG_CATCH_THROW("(stationary) AssembleJacobian: Cannot create Data Evaluator.");
     413              :         }
     414              : 
     415              : ////////////////////////////////////////////////////////////////////////////////
     416              : // Assemble (instationary) Jacobian
     417              : ////////////////////////////////////////////////////////////////////////////////
     418              : 
     419              : public:
     420              :         /**
     421              :          * This function adds the contributions of all passed element discretizations
     422              :          * on one given subset to the global Jacobian in the time-dependent case.
     423              :          * Note, that s_m0 == 1
     424              :          * (This version processes elements in a given interval.)
     425              :          *
     426              :          * \param[in]           vElemDisc               element discretizations
     427              :          * \param[in]           spDomain                domain
     428              :          * \param[in]           dd                              DoF Distribution
     429              :          * \param[in]           iterBegin               element iterator
     430              :          * \param[in]           iterEnd                 element iterator
     431              :          * \param[in]           si                              subset index
     432              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     433              :          * \param[in,out]       J                               jacobian
     434              :          * \param[in]           vSol                    current and previous solutions
     435              :          * \param[in]           s_a0                    scaling factor for stiffness part
     436              :          * \param[in]           spAssTuner              assemble adapter
     437              :          */
     438              :         template <typename TElem, typename TIterator>
     439              :         static void
     440            0 :         AssembleJacobian(       const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     441              :                                                 ConstSmartPtr<domain_type> spDomain,
     442              :                                                 ConstSmartPtr<DoFDistribution> dd,
     443              :                                                 TIterator iterBegin,
     444              :                                                 TIterator iterEnd,
     445              :                                                 int si, bool bNonRegularGrid,
     446              :                                                 matrix_type& J,
     447              :                                                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     448              :                                                 number s_a0,
     449              :                                                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     450              :         {
     451              :         //      check if there are any elements at all, otherwise return immediately
     452            0 :                 if(iterBegin == iterEnd) return;
     453              : 
     454              :         //      reference object id
     455              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     456              : 
     457              :         //      storage for corner coordinates
     458            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     459              : 
     460              :         //      get current time and vector
     461            0 :                 const vector_type& u = *vSol->solution(0);
     462              : 
     463              :         //      create local time series
     464              :                 LocalVectorTimeSeries locTimeSeries;
     465            0 :                 locTimeSeries.read_times(vSol);
     466              : 
     467              :         //      prepare for given elem discs
     468              :                 try
     469              :                 {
     470            0 :                 DataEvaluator<domain_type> Eval(MASS | STIFF | RHS,
     471              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
     472              :                                                    &locTimeSeries);
     473            0 :                 Eval.set_time_point(0);
     474              : 
     475              :         //      prepare element loop
     476            0 :                 Eval.prepare_elem_loop(id, si);
     477              : 
     478              :         //      local algebra
     479              :                 LocalIndices ind; LocalVector locU; LocalMatrix locJ;
     480              : 
     481              :                 EL_PROFILE_BEGIN(Elem_AssembleJacobian);
     482              :         //      Loop over all elements
     483            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     484              :                 {
     485              :                 //      get Element
     486            0 :                         TElem* elem = *iter;
     487              : 
     488              :                 //      get corner coordinates
     489            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     490              : 
     491              :                 //      check if elem is skipped from assembling
     492            0 :                         if(!spAssTuner->element_used(elem)) continue;
     493              : 
     494              :                 //      get global indices
     495            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     496              : 
     497              :                 //      adapt local algebra
     498            0 :                         locU.resize(ind); locJ.resize(ind);
     499              : 
     500              :                 //      read local values of u
     501            0 :                         GetLocalVector(locU, u);
     502              : 
     503              :                 //      read local values of time series
     504            0 :                         if(Eval.time_series_needed())
     505            0 :                                 locTimeSeries.read_values(vSol, ind);
     506              : 
     507              :                 //      prepare element
     508              :                         try
     509              :                         {
     510            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, true);
     511              :                         }
     512            0 :                         UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot prepare element.");
     513              : 
     514              :                 //      reset local algebra
     515            0 :                         locJ = 0.0;
     516              : 
     517              :                         //EL_PROFILE_BEGIN(Elem_add_JA);
     518              :                         //      Assemble JA
     519              :                         try
     520              :                         {
     521            0 :                                 Eval.add_jac_A_elem(locJ, locU, elem, vCornerCoords, PT_INSTATIONARY);
     522            0 :                                 locJ *= s_a0;
     523              : 
     524            0 :                                 Eval.add_jac_A_elem(locJ, locU, elem, vCornerCoords, PT_STATIONARY);
     525              :                         }
     526            0 :                         UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot compute Jacobian (A).");
     527              :                         //EL_PROFILE_END();
     528              : 
     529              :                 //      Assemble JM
     530              :                         try
     531              :                         {
     532            0 :                                 Eval.add_jac_M_elem(locJ, locU, elem, vCornerCoords, PT_INSTATIONARY);
     533              :                         }
     534            0 :                         UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot compute Jacobian (M).");
     535              : 
     536              :                 // send local to global matrix
     537              :                         try{
     538            0 :                                 spAssTuner->add_local_mat_to_global(J, locJ, dd);
     539              :                         }
     540            0 :                         UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot add local matrix.");
     541              : 
     542              :                 }
     543              :                 EL_PROFILE_END();
     544              : 
     545              :         //      finish element loop
     546              :                 try
     547              :                 {
     548            0 :                         Eval.finish_elem_loop();
     549              :                 }
     550            0 :                 UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot finish element loop.");
     551              : 
     552            0 :                 }
     553            0 :                 UG_CATCH_THROW("(instationary) AssembleJacobian: Cannot create Data Evaluator.");
     554              :         }
     555              : 
     556              : ////////////////////////////////////////////////////////////////////////////////
     557              : // Assemble (stationary) Defect
     558              : ////////////////////////////////////////////////////////////////////////////////
     559              : 
     560              : public:
     561              :         /**
     562              :          * This function adds the contributions of all passed element discretizations
     563              :          * on one given subset to the global Defect in the stationary case. (This version
     564              :          * processes elements in a given interval.)
     565              :          *
     566              :          * \param[in]           vElemDisc               element discretizations
     567              :          * \param[in]           spDomain                domain
     568              :          * \param[in]           dd                              DoF Distribution
     569              :          * \param[in]           iterBegin               element iterator
     570              :          * \param[in]           iterEnd                 element iterator
     571              :          * \param[in]           si                              subset index
     572              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     573              :          * \param[in,out]       d                               defect
     574              :          * \param[in]           u                               solution
     575              :          * \param[in]           spAssTuner              assemble adapter
     576              :          */
     577              :         template <typename TElem, typename TIterator>
     578              :         static void
     579            0 :         AssembleDefect( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     580              :                                         ConstSmartPtr<domain_type> spDomain,
     581              :                                         ConstSmartPtr<DoFDistribution> dd,
     582              :                                         TIterator iterBegin,
     583              :                                         TIterator iterEnd,
     584              :                                         int si, bool bNonRegularGrid,
     585              :                                         vector_type& d,
     586              :                                         const vector_type& u,
     587              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     588              :         {
     589              :         //      check if at least one element exists, else return
     590            0 :                 if(iterBegin == iterEnd) return;
     591              : 
     592              :         //      reference object id
     593              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     594              : 
     595              :         //      storage for corner coordinates
     596            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     597              : 
     598              :         //      prepare for given elem discs
     599              :                 try
     600              :                 {
     601            0 :                 DataEvaluator<domain_type> Eval(STIFF | RHS,
     602              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
     603              : 
     604              :         //      prepare element loop
     605            0 :                 Eval.prepare_elem_loop(id, si);
     606              : 
     607              :         //      local indices and local algebra
     608              :                 LocalIndices ind; LocalVector locU, locD, tmpLocD;
     609              : 
     610              :         //      Loop over all elements
     611            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     612              :                 {
     613              :                 //      get Element
     614            0 :                         TElem* elem = *iter;
     615              : 
     616              :                 //      get corner coordinates
     617            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     618              : 
     619              :                 //      check if elem is skipped from assembling
     620            0 :                         if(!spAssTuner->element_used(elem)) continue;
     621              : 
     622              :                 //      get global indices
     623            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     624              : 
     625              :                 //      adapt local algebra
     626            0 :                         locU.resize(ind); locD.resize(ind); tmpLocD.resize(ind);
     627              : 
     628              :                 //      read local values of u
     629            0 :                         GetLocalVector(locU, u);
     630              : 
     631              :                 //      prepare element
     632              :                         try
     633              :                         {
     634            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind);
     635              :                         }
     636            0 :                         UG_CATCH_THROW("(stationary) AssembleDefect: Cannot prepare element.");
     637              : 
     638              :                 //      ANALOG to 'domain_disc_elem()' -  modifies the solution, used
     639              :                 //      for computing the defect
     640            0 :                         if( spAssTuner->modify_solution_enabled() )
     641              :                         {
     642              :                                 LocalVector& modLocU = locU;
     643              :                                 try{
     644            0 :                                         spAssTuner->modify_LocalSol(modLocU, locU, dd);
     645            0 :                                 } UG_CATCH_THROW("Cannot modify local solution.");
     646              : 
     647              :                                 // recopy modified LocalVector:
     648            0 :                                 locU = modLocU;
     649              :                         }
     650              : 
     651              :                 //      reset local algebra
     652            0 :                         locD = 0.0;
     653              : 
     654              :                 //      Assemble A
     655              :                         try
     656              :                         {
     657            0 :                                 Eval.add_def_A_elem(locD, locU, elem, vCornerCoords);
     658              :                         }
     659            0 :                         UG_CATCH_THROW("(stationary) AssembleDefect: Cannot compute Defect (A).");
     660              : 
     661              :                 //      Assemble rhs
     662              :                         try
     663              :                         {
     664            0 :                                 tmpLocD = 0.0;
     665            0 :                                 Eval.add_rhs_elem(tmpLocD, elem, vCornerCoords);
     666            0 :                                 locD.scale_append(-1, tmpLocD);
     667              : 
     668              :                         }
     669            0 :                         UG_CATCH_THROW("(stationary) AssembleDefect: Cannot compute Rhs.");
     670              : 
     671              :                 //      send local to global defect
     672              :                         try{
     673            0 :                                 spAssTuner->add_local_vec_to_global(d, locD, dd);
     674              :                         }
     675            0 :                         UG_CATCH_THROW("(stationary) AssembleDefect: Cannot add local vector.");
     676              :                 }
     677              : 
     678              :         //      finish element loop
     679              :                 try
     680              :                 {
     681            0 :                         Eval.finish_elem_loop();
     682              :                 }
     683            0 :                 UG_CATCH_THROW("(stationary) AssembleDefect: Cannot finish element loop.");
     684              : 
     685              :                 }
     686            0 :                 UG_CATCH_THROW("(stationary) AssembleDefect: Cannot create Data Evaluator.");
     687              :         }
     688              : 
     689              : ////////////////////////////////////////////////////////////////////////////////
     690              : // Assemble (instationary) Defect
     691              : ////////////////////////////////////////////////////////////////////////////////
     692              : 
     693              : public:
     694              :         /**
     695              :          * This function adds the contributions of all passed element discretizations
     696              :          * on one given subset to the global Defect in the instationary case. (This version
     697              :          * processes elements in a given interval.)
     698              :          *
     699              :          * \param[in]           vElemDisc               element discretizations
     700              :          * \param[in]           spDomain                domain
     701              :          * \param[in]           dd                              DoF Distribution
     702              :          * \param[in]           iterBegin               element iterator
     703              :          * \param[in]           iterEnd                 element iterator
     704              :          * \param[in]           si                              subset index
     705              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     706              :          * \param[in,out]       d                               defect
     707              :          * \param[in]           vSol                    current and previous solutions
     708              :          * \param[in]           vScaleMass              scaling factors for mass part
     709              :          * \param[in]           vScaleStiff             scaling factors for stiffness part
     710              :          * \param[in]           spAssTuner              assemble adapter
     711              :          */
     712              :         template <typename TElem, typename TIterator>
     713              :         static void
     714            0 :         AssembleDefect( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     715              :                                         ConstSmartPtr<domain_type> spDomain,
     716              :                                         ConstSmartPtr<DoFDistribution> dd,
     717              :                                         TIterator iterBegin,
     718              :                                         TIterator iterEnd,
     719              :                                         int si, bool bNonRegularGrid,
     720              :                                         vector_type& d,
     721              :                                         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     722              :                                         const std::vector<number>& vScaleMass,
     723              :                                         const std::vector<number>& vScaleStiff,
     724              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     725              :         {
     726              :         //      check if there are any elements at all, otherwise return immediately
     727            0 :                 if(iterBegin == iterEnd) return;
     728              : 
     729              :         //      reference object id
     730              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     731              : 
     732              :         //      storage for corner coordinates
     733            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     734              : 
     735              :         //      check time scheme
     736            0 :                 if(vScaleMass.size() != vScaleStiff.size())
     737            0 :                         UG_THROW("(instationary) AssembleDefect: s_a and s_m must have same size.");
     738              : 
     739            0 :                 if(vSol->size() < vScaleStiff.size())
     740            0 :                         UG_THROW("(instationary) AssembleDefect: Time stepping scheme needs at "
     741              :                                         "least "<<vScaleStiff.size()<<" time steps, but only "<<
     742              :                                         vSol->size() << " passed.");
     743              : 
     744              :         //      create local time series
     745              :                 LocalVectorTimeSeries locTimeSeries;
     746            0 :                 locTimeSeries.read_times(vSol);
     747              : 
     748              :         //      prepare for given elem discs
     749              :                 try
     750              :                 {
     751            0 :                 DataEvaluator<domain_type> Eval(MASS | STIFF | RHS | EXPL,
     752              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
     753              :                                                    &locTimeSeries, &vScaleMass, &vScaleStiff);
     754              : 
     755              :         //      prepare element loop
     756            0 :                 Eval.prepare_elem_loop(id, si);
     757              : 
     758              :         //      local indices and local algebra
     759              :                 LocalIndices ind; LocalVector locD, tmpLocD;
     760              : 
     761              :         //      Loop over all elements
     762            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     763              :                 {
     764              :                 //      get Element
     765            0 :                         TElem* elem = *iter;
     766              : 
     767              :                 //      get corner coordinates
     768            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     769              : 
     770              :                 //      check if elem is skipped from assembling
     771            0 :                         if(!spAssTuner->element_used(elem)) continue;
     772              : 
     773              :                 //      get global indices
     774            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     775              : 
     776              :                 //      adapt local algebra
     777            0 :                         locD.resize(ind); tmpLocD.resize(ind);
     778              : 
     779              :                 //      read local values of time series
     780            0 :                         locTimeSeries.read_values(vSol, ind);
     781              : 
     782              :                 //      reset contribution of this element
     783            0 :                         locD = 0.0;
     784              : 
     785              :                 //      loop all time points and assemble them
     786            0 :                         for(size_t t = 0; t < vScaleStiff.size(); ++t)
     787              :                         {
     788            0 :                                 number scale_stiff = vScaleStiff[t];
     789              :                                 
     790              :                         //      get local solution at timepoint
     791              :                                 LocalVector& locU = locTimeSeries.solution(t);
     792            0 :                                 Eval.set_time_point(t);
     793              : 
     794              :                         //      prepare element
     795              :                                 try
     796              :                                 {
     797            0 :                                         Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, false);
     798              :                                 }
     799            0 :                                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot prepare element.");
     800              : 
     801              :                         //      Assemble M
     802              :                                 try
     803              :                                 {
     804            0 :                                         tmpLocD = 0.0;
     805            0 :                                         Eval.add_def_M_elem(tmpLocD, locU, elem, vCornerCoords, PT_INSTATIONARY);
     806            0 :                                         locD.scale_append(vScaleMass[t], tmpLocD);
     807              :                                 }
     808            0 :                                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot compute Defect (M).");
     809              : 
     810              :                         //      Assemble A
     811              :                                 try
     812              :                                 {
     813            0 :                                         if(scale_stiff != 0.0)
     814              :                                         {
     815            0 :                                                 tmpLocD = 0.0;
     816            0 :                                                 Eval.add_def_A_elem(tmpLocD, locU, elem, vCornerCoords, PT_INSTATIONARY);
     817            0 :                                                 locD.scale_append(scale_stiff, tmpLocD);
     818              :                                         }
     819              : 
     820            0 :                                         if(t == 0)
     821            0 :                                                 Eval.add_def_A_elem(locD, locU, elem, vCornerCoords, PT_STATIONARY);
     822              :                                 }
     823            0 :                                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot compute Defect (A).");
     824              : 
     825              : 
     826              :                                 // Assemble defect for explicit reaction_rate, reaction and source
     827            0 :                                 if( t == 1 ) // only valid at lowest timediscretization order
     828              :                                 {
     829            0 :                                         tmpLocD = 0.0;
     830              :                                         try
     831              :                                         {
     832            0 :                                          Eval.add_def_A_expl_elem(tmpLocD, locU, elem, vCornerCoords, PT_INSTATIONARY);
     833              :                                         }
     834            0 :                                         UG_CATCH_THROW("(instationary) AssembleDefect explizit: Cannot compute Defect (A).");
     835              : 
     836              : //                                      UG_ASSERT(vScaleStiff.size() == 2, "Only one step method supported.");
     837            0 :                                         const number dt = vSol->time(0)-vSol->time(1);
     838            0 :                                         locD.scale_append(dt, tmpLocD);
     839              :                                 }
     840              : 
     841              : 
     842              :                         //      Assemble rhs
     843              :                                 try
     844              :                                 {
     845            0 :                                         if(scale_stiff != 0.0)
     846              :                                         {
     847            0 :                                                 tmpLocD = 0.0;
     848            0 :                                                 Eval.add_rhs_elem(tmpLocD, elem, vCornerCoords, PT_INSTATIONARY);
     849            0 :                                                 locD.scale_append( - scale_stiff, tmpLocD);
     850              :                                         }
     851              : 
     852            0 :                                         if(t == 0)
     853              :                                         {
     854            0 :                                                 tmpLocD = 0.0;
     855            0 :                                                 Eval.add_rhs_elem(tmpLocD, elem, vCornerCoords, PT_STATIONARY);
     856            0 :                                                 locD.scale_append( -1.0, tmpLocD);
     857              :                                         }
     858              :                                 }
     859            0 :                                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot compute Rhs.");
     860              :                         }
     861              : 
     862              :                 //      send local to global defect
     863              :                         try{
     864            0 :                                 spAssTuner->add_local_vec_to_global(d, locD, dd);
     865              :                         }
     866            0 :                         UG_CATCH_THROW("(instationary) AssembleDefect: Cannot add local vector.");
     867              :                 }
     868              : 
     869              :         //      finish element loop
     870              :                 try
     871              :                 {
     872            0 :                         Eval.finish_elem_loop();
     873              :                 }
     874            0 :                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot finish element loop.");
     875              : 
     876              :                 }
     877            0 :                 UG_CATCH_THROW("(instationary) AssembleDefect: Cannot create Data Evaluator.");
     878              :         }
     879              : 
     880              : ////////////////////////////////////////////////////////////////////////////////
     881              : // Assemble (stationary) Linear problem
     882              : ////////////////////////////////////////////////////////////////////////////////
     883              : 
     884              : public:
     885              :         /**
     886              :          * This function adds the contributions of all passed element discretizations
     887              :          * on one given subset to the global Matrix and the global Right-Hand Side
     888              :          * of the Linear problem in the stationary case. (This version processes
     889              :          * elements in a given interval.)
     890              :          *
     891              :          * \param[in]           vElemDisc               element discretizations
     892              :          * \param[in]           spDomain                domain
     893              :          * \param[in]           dd                              DoF Distribution
     894              :          * \param[in]           iterBegin               element iterator
     895              :          * \param[in]           iterEnd                 element iterator
     896              :          * \param[in]           si                              subset index
     897              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
     898              :          * \param[in,out]       A                               Matrix
     899              :          * \param[in,out]       rhs                             Right-hand side
     900              :          * \param[in]           spAssTuner              assemble adapter
     901              :          */
     902              :         template <typename TElem, typename TIterator>
     903              :         static void
     904            0 :         AssembleLinear( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
     905              :                                         ConstSmartPtr<domain_type> spDomain,
     906              :                                         ConstSmartPtr<DoFDistribution> dd,
     907              :                                         TIterator iterBegin,
     908              :                                         TIterator iterEnd,
     909              :                                         int si, bool bNonRegularGrid,
     910              :                                         matrix_type& A,
     911              :                                         vector_type& rhs,
     912              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
     913              :         {
     914              :         //      check if there are any elements at all, otherwise return immediately
     915            0 :                 if(iterBegin == iterEnd) return;
     916              : 
     917              :         //      reference object id
     918              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
     919              : 
     920              :         //      storage for corner coordinates
     921            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
     922              : 
     923              :         //      prepare for given elem discs
     924              :                 try
     925              :                 {
     926            0 :                 DataEvaluator<domain_type> Eval(STIFF | RHS,
     927              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
     928              : 
     929              :                 UG_DLOG(DID_ELEM_DISC_ASSEMBLE_UTIL, 2, ">>OCT_DISC_DEBUG: " << "elem_disc_assemble_util.h: " << "AssembleLinear(): DataEvaluator(): " << id << std::endl);
     930              : 
     931              :         //      prepare loop
     932            0 :                 Eval.prepare_elem_loop(id, si);
     933              : 
     934              :                 UG_DLOG(DID_ELEM_DISC_ASSEMBLE_UTIL, 2, ">>OCT_DISC_DEBUG: " << "elem_disc_assemble_util.h: " << "AssembleLinear(): prepare_elem_loop(): " << id << std::endl);
     935              : 
     936              :         //      local indices and local algebra
     937              :                 LocalIndices ind; LocalVector locRhs; LocalMatrix locA;
     938              : 
     939              :         //      Loop over all elements
     940            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     941              :                 {
     942              :                 //      get Element
     943            0 :                         TElem* elem = *iter;
     944              : 
     945              :                 //      get corner coordinates
     946            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
     947              : 
     948              :                 //      check if elem is skipped from assembling
     949            0 :                         if(!spAssTuner->element_used(elem)) continue;
     950              : 
     951              :                 //      get global indices
     952            0 :                         dd->indices(elem, ind, Eval.use_hanging());
     953              : 
     954              :                 //      adapt local algebra
     955            0 :                         locRhs.resize(ind); locA.resize(ind);
     956              : 
     957              :                 //      prepare element
     958              :                         try
     959              :                         {
     960              :                                 UG_DLOG(DID_ELEM_DISC_ASSEMBLE_UTIL, 2, ">>OCT_DISC_DEBUG: " << "elem_disc_assemble_util.h: " << "AssembleLinear(): prepare_elem(): " << id << std::endl);
     961              :                                 for(int i = 0; i < 8; ++i)
     962              :                                         UG_DLOG(DID_ELEM_DISC_ASSEMBLE_UTIL, 2, ">>OCT_DISC_DEBUG: " << "elem_disc_assemble_util.h: " << "AssembleLinear(): prepare_elem(): " << "vCornerCoords " << i << ": " << vCornerCoords[i] << std::endl);
     963              : 
     964            0 :                                 Eval.prepare_elem(locRhs, elem, id, vCornerCoords, ind, true);
     965              :                         }
     966            0 :                         UG_CATCH_THROW("(stationary) AssembleLinear: Cannot prepare element.");
     967              : 
     968              :                 //      reset local algebra
     969            0 :                         locA = 0.0;
     970            0 :                         locRhs = 0.0;
     971              : 
     972              :                 //      Assemble JA
     973              :                         try
     974              :                         {
     975            0 :                                 Eval.add_jac_A_elem(locA, locRhs, elem, vCornerCoords);
     976              :                         }
     977            0 :                         UG_CATCH_THROW("(stationary) AssembleLinear: Cannot compute Jacobian (A).");
     978              : 
     979              :                 //      Assemble rhs
     980              :                         try
     981              :                         {
     982            0 :                                 Eval.add_rhs_elem(locRhs, elem, vCornerCoords);
     983              :                         }
     984            0 :                         UG_CATCH_THROW("(stationary) AssembleLinear: Cannot compute Rhs.");
     985              : 
     986              :                 //      send local to global matrix & rhs
     987              :                         try{
     988            0 :                                 spAssTuner->add_local_mat_to_global(A, locA, dd);
     989            0 :                                 spAssTuner->add_local_vec_to_global(rhs, locRhs, dd);
     990              :                         }
     991            0 :                         UG_CATCH_THROW("(stationary) AssembleLinear: Cannot add local vector/matrix.");
     992              :                 }
     993              : 
     994              :         //      finish element loop
     995              :                 try
     996              :                 {
     997            0 :                         Eval.finish_elem_loop();
     998              :                 }
     999            0 :                 UG_CATCH_THROW("(stationary) AssembleLinear: Cannot finish element loop.");
    1000              : 
    1001            0 :                 }
    1002            0 :                 UG_CATCH_THROW("(stationary) AssembleLinear: Cannot create Data Evaluator.");
    1003              :         }
    1004              : 
    1005              : ////////////////////////////////////////////////////////////////////////////////
    1006              : // Assemble (instationary) Linear problem
    1007              : ////////////////////////////////////////////////////////////////////////////////
    1008              : 
    1009              : public:
    1010              :         /**
    1011              :          * This function adds the contributions of all passed element discretizations
    1012              :          * on one given subset to the global Matrix and the global Right-Hand Side
    1013              :          * of the Linear problem in the time-dependent case. (This version processes
    1014              :          * elements in a given interval.)
    1015              :          *
    1016              :          * \param[in]           vElemDisc               element discretizations
    1017              :          * \param[in]           spDomain                domain
    1018              :          * \param[in]           dd                              DoF Distribution
    1019              :          * \param[in]           iterBegin               element iterator
    1020              :          * \param[in]           iterEnd                 element iterator
    1021              :          * \param[in]           si                              subset index
    1022              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1023              :          * \param[in,out]       A                               Matrix
    1024              :          * \param[in,out]       rhs                             Right-hand side
    1025              :          * \param[in]           vSol                    current and previous solutions
    1026              :          * \param[in]           vScaleMass              scaling factors for mass part
    1027              :          * \param[in]           vScaleStiff             scaling factors for stiffness part
    1028              :          * \param[in]           spAssTuner              assemble adapter
    1029              :          */
    1030              :         template <typename TElem, typename TIterator>
    1031              :         static void
    1032            0 :         AssembleLinear( const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1033              :                                         ConstSmartPtr<domain_type> spDomain,
    1034              :                                         ConstSmartPtr<DoFDistribution> dd,
    1035              :                                         TIterator iterBegin,
    1036              :                                         TIterator iterEnd,
    1037              :                                         int si, bool bNonRegularGrid,
    1038              :                                         matrix_type& A,
    1039              :                                         vector_type& rhs,
    1040              :                                         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1041              :                                         const std::vector<number>& vScaleMass,
    1042              :                                         const std::vector<number>& vScaleStiff,
    1043              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
    1044              :         {
    1045              :         //      check if there are any elements at all, otherwise return immediately
    1046            0 :                 if(iterBegin == iterEnd) return;
    1047              : 
    1048              :         //      reference object id
    1049              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1050              : 
    1051              :         //      storage for corner coordinates
    1052            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1053              : 
    1054              :         //      check time scheme
    1055            0 :                 if(vScaleMass.size() != vScaleStiff.size())
    1056            0 :                         UG_THROW("(instationary) AssembleLinear: s_a and s_m must have same size.");
    1057              : 
    1058            0 :                 if(vSol->size() < vScaleStiff.size())
    1059            0 :                         UG_THROW("(instationary) AssembleLinear: Time stepping scheme needs at "
    1060              :                                         "least "<<vScaleStiff.size()<<" time steps, but only "<<
    1061              :                                         vSol->size() << " passed.");
    1062              : 
    1063              :         //      create local time solution
    1064              :                 LocalVectorTimeSeries locTimeSeries;
    1065            0 :                 locTimeSeries.read_times(vSol);
    1066              : 
    1067              :         //      prepare for given elem discs
    1068              :                 try
    1069              :                 {
    1070            0 :                 DataEvaluator<domain_type> Eval(MASS | STIFF | RHS,
    1071              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1072              :                                                    &locTimeSeries, &vScaleMass, &vScaleStiff);
    1073              : 
    1074              :         //      prepare loop
    1075            0 :                 Eval.prepare_elem_loop(id, si);
    1076              : 
    1077              :         //      local algebra
    1078              :                 LocalIndices ind; LocalVector locRhs, tmpLocRhs; LocalMatrix locA, tmpLocA;
    1079              : 
    1080              :         //      Loop over all elements
    1081            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1082              :                 {
    1083              :                 //      get Element
    1084            0 :                         TElem* elem = *iter;
    1085              : 
    1086              :                 //      get corner coordinates
    1087            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1088              : 
    1089              :                 //      check if elem is skipped from assembling
    1090            0 :                         if(!spAssTuner->element_used(elem)) continue;
    1091              : 
    1092              :                 //      get global indices
    1093            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1094              : 
    1095              :                 //      adapt local algebra
    1096            0 :                         locRhs.resize(ind); tmpLocRhs.resize(ind);
    1097              :                         locA.resize(ind); tmpLocA.resize(ind);
    1098              : 
    1099              :                 //      read local values of time series
    1100            0 :                         locTimeSeries.read_values(vSol, ind);
    1101            0 :                         Eval.set_time_point(0);
    1102              : 
    1103              :                 //      reset element contribution
    1104            0 :                         locA = 0.0; locRhs = 0.0;
    1105              : 
    1106              :                 /////////////////////
    1107              :                 //      current time step
    1108              : 
    1109              :                 //      get local solution at time point
    1110              :                         LocalVector& locU = locTimeSeries.solution(0);
    1111              : 
    1112              :                 //      prepare element
    1113              :                         try
    1114              :                         {
    1115            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, true);
    1116              :                         }
    1117            0 :                         UG_CATCH_THROW("(instationary) AssembleLinear: Cannot prepare element.");
    1118              : 
    1119            0 :                 if (!spAssTuner->matrix_is_const())
    1120              :                 {
    1121              :                 //      Assemble JM
    1122              :                         try
    1123              :                         {
    1124            0 :                                 tmpLocA = 0.0;
    1125            0 :                                 Eval.add_jac_M_elem(tmpLocA, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1126            0 :                                 locA.scale_append(vScaleMass[0], tmpLocA);
    1127              :                         }
    1128            0 :                         UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Jacobian (M).");
    1129              : 
    1130              :                 //      Assemble JA
    1131              :                         try
    1132              :                         {
    1133            0 :                                 if (vScaleStiff[0] != 0.0)
    1134              :                                 {
    1135            0 :                                         tmpLocA = 0.0;
    1136            0 :                                         Eval.add_jac_A_elem(tmpLocA, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1137            0 :                                         locA.scale_append(vScaleStiff[0], tmpLocA);
    1138              :                                 }
    1139            0 :                                 Eval.add_jac_A_elem(locA, locU, elem, vCornerCoords, PT_STATIONARY);
    1140              :                         }
    1141            0 :                         UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Jacobian (A).");
    1142              :                 }
    1143              :                 //      Assemble rhs
    1144              :                         try
    1145              :                         {
    1146            0 :                                 if (vScaleStiff[0] != 0.0)
    1147              :                                 {
    1148            0 :                                         tmpLocRhs = 0.0;
    1149            0 :                                         Eval.add_rhs_elem(tmpLocRhs, elem, vCornerCoords, PT_INSTATIONARY);
    1150            0 :                                         locRhs.scale_append(vScaleStiff[0], tmpLocRhs);
    1151              :                                 }
    1152            0 :                                 Eval.add_rhs_elem(locRhs, elem, vCornerCoords, PT_STATIONARY);
    1153              :                         }
    1154            0 :                         UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Rhs.");
    1155              : 
    1156              :                 ///////////////////
    1157              :                 //      old time steps
    1158              : 
    1159              :                 //      loop all old time points
    1160            0 :                         for(size_t t = 1; t < vScaleStiff.size(); ++t)
    1161              :                         {
    1162              :                         //      get local solution at time point
    1163              :                                 LocalVector& locU = locTimeSeries.solution(t);
    1164            0 :                                 Eval.set_time_point(t);
    1165            0 :                                 number scaleStiff = vScaleStiff[t];
    1166              : 
    1167              :                         //      prepare element
    1168              :                                 try
    1169              :                                 {
    1170            0 :                                         Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, false);
    1171              :                                 }
    1172            0 :                                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot prepare element.");
    1173              : 
    1174              :                         //      Assemble dM
    1175              :                                 try
    1176              :                                 {
    1177            0 :                                         tmpLocRhs = 0.0;
    1178            0 :                                         Eval.add_def_M_elem(tmpLocRhs, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1179            0 :                                         locRhs.scale_append(-vScaleMass[t], tmpLocRhs);
    1180              :                                 }
    1181            0 :                                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Jacobian (M).");
    1182              : 
    1183              :                         //      Assemble dA
    1184              :                                 try
    1185              :                                 {
    1186            0 :                                         if (scaleStiff != 0.0)
    1187              :                                         {
    1188            0 :                                                 tmpLocRhs = 0.0;
    1189            0 :                                                 Eval.add_def_A_elem(tmpLocRhs, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1190            0 :                                                 locRhs.scale_append(-scaleStiff, tmpLocRhs);
    1191              :                                         }
    1192              :                                 }
    1193            0 :                                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Jacobian (A).");
    1194              : 
    1195              :                         //      Assemble rhs
    1196              :                                 try
    1197              :                                 {
    1198            0 :                                         if (scaleStiff != 0.0)
    1199              :                                         {
    1200            0 :                                                 tmpLocRhs = 0.0;
    1201            0 :                                                 Eval.add_rhs_elem(tmpLocRhs, elem, vCornerCoords, PT_INSTATIONARY);
    1202            0 :                                                 locRhs.scale_append(scaleStiff, tmpLocRhs);
    1203              :                                         }
    1204              :                                 }
    1205            0 :                                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot compute Rhs.");
    1206              :                         }
    1207              : 
    1208              :                 //      send local to global matrix & rhs
    1209              :                         try{
    1210            0 :                                 if (!spAssTuner->matrix_is_const())
    1211            0 :                                         spAssTuner->add_local_mat_to_global(A, locA, dd);
    1212            0 :                                 spAssTuner->add_local_vec_to_global(rhs, locRhs, dd);
    1213              :                         }
    1214            0 :                         UG_CATCH_THROW("(instationary) AssembleLinear: Cannot add local vector/matrix.");
    1215              :                 }
    1216              : 
    1217              :         //      finish element loop
    1218              :                 try
    1219              :                 {
    1220            0 :                         Eval.finish_elem_loop();
    1221              :                 }
    1222            0 :                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot finish element loop.");
    1223              : 
    1224            0 :                 }
    1225            0 :                 UG_CATCH_THROW("(instationary) AssembleLinear: Cannot create Data Evaluator.");
    1226              :         }
    1227              : 
    1228              : ////////////////////////////////////////////////////////////////////////////////
    1229              : // Assemble Rhs (of a stationary problem)
    1230              : ////////////////////////////////////////////////////////////////////////////////
    1231              : 
    1232              : public:
    1233              :         /**
    1234              :          * This function adds the contributions of all passed element discretizations
    1235              :          * on one given subset to the global Right-Hand Side. (This version processes
    1236              :          * elements in a given interval.)
    1237              :          *
    1238              :          * \param[in]           vElemDisc               element discretizations
    1239              :          * \param[in]           spDomain                domain
    1240              :          * \param[in]           dd                              DoF Distribution
    1241              :          * \param[in]           iterBegin               element iterator
    1242              :          * \param[in]           iterEnd                 element iterator
    1243              :          * \param[in]           si                              subset index
    1244              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1245              :          * \param[in,out]       rhs                             Right-hand side
    1246              :          * \param[in]           u                               solution
    1247              :          * \param[in]           spAssTuner              assemble adapter
    1248              :          */
    1249              :         template <typename TElem, typename TIterator>
    1250              :         static void
    1251            0 :         AssembleRhs(    const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1252              :                                         ConstSmartPtr<domain_type> spDomain,
    1253              :                                         ConstSmartPtr<DoFDistribution> dd,
    1254              :                                         TIterator iterBegin,
    1255              :                                         TIterator iterEnd,
    1256              :                                         int si, bool bNonRegularGrid,
    1257              :                                         vector_type& rhs,
    1258              :                                         const vector_type& u,
    1259              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
    1260              :         {
    1261              :         //      check if there are any elements at all, otherwise return immediately
    1262            0 :                 if(iterBegin == iterEnd) return;
    1263              : 
    1264              :         //      reference object id
    1265              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1266              : 
    1267              :         //      storage for corner coordinates
    1268            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1269              : 
    1270              :         //      prepare for given elem discs
    1271              :                 try
    1272              :                 {
    1273            0 :                 DataEvaluator<domain_type> Eval(RHS,
    1274              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
    1275              : 
    1276              :         //      prepare loop
    1277            0 :                 Eval.prepare_elem_loop(id, si);
    1278              : 
    1279              :         //      local indices and local algebra
    1280              :                 LocalIndices ind; LocalVector locU, locRhs;
    1281              : 
    1282              :         //      Loop over all elements
    1283            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1284              :                 {
    1285              :                 //      get Element
    1286            0 :                         TElem* elem = *iter;
    1287              : 
    1288              :                 //      get corner coordinates
    1289            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1290              : 
    1291              :                 //      check if elem is skipped from assembling
    1292            0 :                         if(!spAssTuner->element_used(elem)) continue;
    1293              : 
    1294              :                 //      get global indices
    1295            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1296              : 
    1297              :                 //      adapt local algebra
    1298            0 :                         locU.resize(ind); locRhs.resize(ind);
    1299              : 
    1300              :                 //      read local values of u
    1301            0 :                         GetLocalVector(locU, u);
    1302              : 
    1303              :                 //      prepare element
    1304              :                         try
    1305              :                         {
    1306            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind);
    1307              :                         }
    1308            0 :                         UG_CATCH_THROW("AssembleRhs: Cannot prepare element.");
    1309              : 
    1310              :                 //      reset local algebra
    1311            0 :                         locRhs = 0.0;
    1312              : 
    1313              :                 //      Assemble rhs
    1314              :                         try
    1315              :                         {
    1316            0 :                                 Eval.add_rhs_elem(locRhs, elem, vCornerCoords);
    1317              :                         }
    1318            0 :                         UG_CATCH_THROW("AssembleRhs: Cannot compute Rhs.");
    1319              : 
    1320              :                 //      send local to global rhs
    1321              :                         try{
    1322            0 :                                 spAssTuner->add_local_vec_to_global(rhs, locRhs, dd);
    1323              :                         }
    1324            0 :                         UG_CATCH_THROW("AssembleRhs: Cannot add local vector.");
    1325              :                 }
    1326              : 
    1327              :         //      finish element loop
    1328              :                 try
    1329              :                 {
    1330            0 :                         Eval.finish_elem_loop();
    1331              :                 }
    1332            0 :                 UG_CATCH_THROW("AssembleRhs: Cannot finish element loop.");
    1333              : 
    1334              :                 }
    1335            0 :                 UG_CATCH_THROW("AssembleRhs: Cannot create Data Evaluator.");
    1336              :         }
    1337              : 
    1338              : ////////////////////////////////////////////////////////////////////////////////
    1339              : // Assemble (instationary) Rhs
    1340              : ////////////////////////////////////////////////////////////////////////////////
    1341              : 
    1342              : public:
    1343              :         /**
    1344              :          * This function adds the contributions of all passed element discretizations
    1345              :          * on one given subset to the global Right-Hand Side in the time-dependent case.
    1346              :          * (This version processes elements in a given interval.)
    1347              :          *
    1348              :          * \param[in]           vElemDisc               element discretizations
    1349              :          * \param[in]           spDomain                domain
    1350              :          * \param[in]           dd                              DoF Distribution
    1351              :          * \param[in]           iterBegin               element iterator
    1352              :          * \param[in]           iterEnd                 element iterator
    1353              :          * \param[in]           si                              subset index
    1354              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1355              :          * \param[in,out]       rhs                             Right-hand side
    1356              :          * \param[in]           vSol                    current and previous solutions
    1357              :          * \param[in]           vScaleMass              scaling factors for mass part
    1358              :          * \param[in]           vScaleStiff             scaling factors for stiffness part
    1359              :          * \param[in]           spAssTuner              assemble adapter
    1360              :          */
    1361              :         template <typename TElem, typename TIterator>
    1362              :         static void
    1363            0 :         AssembleRhs(    const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1364              :                                         ConstSmartPtr<domain_type> spDomain,
    1365              :                                         ConstSmartPtr<DoFDistribution> dd,
    1366              :                                         TIterator iterBegin,
    1367              :                                         TIterator iterEnd,
    1368              :                                         int si, bool bNonRegularGrid,
    1369              :                                         vector_type& rhs,
    1370              :                                         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1371              :                                         const std::vector<number>& vScaleMass,
    1372              :                                         const std::vector<number>& vScaleStiff,
    1373              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
    1374              :         {
    1375              :         //      check if there are any elements at all, otherwise return immediately
    1376            0 :                 if(iterBegin == iterEnd) return;
    1377              : 
    1378              :         //      reference object id
    1379              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1380              : 
    1381              :         //      storage for corner coordinates
    1382            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1383              : 
    1384              :         //      check time scheme
    1385            0 :                 if(vScaleMass.size() != vScaleStiff.size())
    1386            0 :                         UG_THROW("(instationary) AssembleRhs: s_a and s_m must have same size.");
    1387              : 
    1388            0 :                 if(vSol->size() < vScaleStiff.size())
    1389            0 :                         UG_THROW("(instationary) AssembleRhs: Time stepping scheme needs at "
    1390              :                                         "least "<<vScaleStiff.size()<<" time steps, but only "<<
    1391              :                                         vSol->size() << " passed.");
    1392              : 
    1393              :         //      get current time
    1394              :                 LocalVectorTimeSeries locTimeSeries;
    1395            0 :                 locTimeSeries.read_times(vSol);
    1396              : 
    1397              :         //      prepare for given elem discs
    1398              :                 try
    1399              :                 {
    1400            0 :                 DataEvaluator<domain_type> Eval(MASS | STIFF | RHS,
    1401              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1402              :                                                    &locTimeSeries, &vScaleMass, &vScaleStiff);
    1403              : 
    1404              :         //      prepare loop
    1405            0 :                 Eval.prepare_elem_loop(id, si);
    1406              : 
    1407              :         //      local algebra
    1408              :                 LocalIndices ind; LocalVector locRhs, tmpLocRhs;
    1409              : 
    1410              :         //      Loop over all elements
    1411            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1412              :                 {
    1413              :                 //      get Element
    1414            0 :                         TElem* elem = *iter;
    1415              : 
    1416              :                 //      get corner coordinates
    1417            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1418              : 
    1419              :                 //      check if elem is skipped from assembling
    1420            0 :                         if(!spAssTuner->element_used(elem)) continue;
    1421              : 
    1422              :                 //      get global indices
    1423            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1424              : 
    1425              :                 //      adapt local algebra
    1426            0 :                         locRhs.resize(ind); tmpLocRhs.resize(ind);
    1427              : 
    1428              :                 //      read local values of time series
    1429            0 :                         locTimeSeries.read_values(vSol, ind);
    1430            0 :                         Eval.set_time_point(0);
    1431              : 
    1432              :                 //      reset element contribution
    1433            0 :                         locRhs = 0.0;
    1434              : 
    1435              :                 /////////////////////
    1436              :                 //      current time step
    1437              : 
    1438              :                 //      get local solution at time point
    1439              :                         LocalVector& locU = locTimeSeries.solution(0);
    1440              : 
    1441              :                 //      prepare element
    1442              :                         try
    1443              :                         {
    1444            0 :                                 Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, false);
    1445              :                         }
    1446            0 :                         UG_CATCH_THROW("(instationary) AssembleRhs: Cannot prepare element.");
    1447              : 
    1448              :                 //      Assemble rhs
    1449              :                         try
    1450              :                         {
    1451            0 :                                 tmpLocRhs = 0.0;
    1452            0 :                                 Eval.add_rhs_elem(tmpLocRhs, elem, vCornerCoords, PT_INSTATIONARY);
    1453            0 :                                 locRhs.scale_append(vScaleStiff[0], tmpLocRhs);
    1454              : 
    1455            0 :                                 Eval.add_rhs_elem(locRhs, elem, vCornerCoords, PT_STATIONARY);
    1456              :                         }
    1457            0 :                         UG_CATCH_THROW("(instationary) AssembleRhs: Cannot compute Rhs.");
    1458              : 
    1459              :                 ///////////////////
    1460              :                 //      old time steps
    1461              : 
    1462              :                 //      loop all old time points
    1463            0 :                         for(size_t t = 1; t < vScaleStiff.size(); ++t)
    1464              :                         {
    1465              :                         //      get local solution at time point
    1466              :                                 LocalVector& locU = locTimeSeries.solution(t);
    1467            0 :                                 Eval.set_time_point(t);
    1468              : 
    1469              :                         //      prepare element
    1470              :                                 try
    1471              :                                 {
    1472            0 :                                         Eval.prepare_elem(locU, elem, id, vCornerCoords, ind, false);
    1473              :                                 }
    1474            0 :                                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot prepare element.");
    1475              : 
    1476              :                         //      Assemble dM
    1477              :                                 try
    1478              :                                 {
    1479            0 :                                         tmpLocRhs = 0.0;
    1480            0 :                                         Eval.add_def_M_elem(tmpLocRhs, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1481            0 :                                         locRhs.scale_append(-vScaleMass[t], tmpLocRhs);
    1482              :                                 }
    1483            0 :                                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot compute Jacobian (M).");
    1484              : 
    1485              :                         //      Assemble dA
    1486              :                                 try
    1487              :                                 {
    1488            0 :                                         tmpLocRhs = 0.0;
    1489            0 :                                         Eval.add_def_A_elem(tmpLocRhs, locU, elem, vCornerCoords, PT_INSTATIONARY);
    1490            0 :                                         locRhs.scale_append(-vScaleStiff[t], tmpLocRhs);
    1491              :                                 }
    1492            0 :                                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot compute Jacobian (A).");
    1493              : 
    1494              :                         //      Assemble rhs
    1495              :                                 try
    1496              :                                 {
    1497            0 :                                         tmpLocRhs = 0.0;
    1498            0 :                                         Eval.add_rhs_elem(tmpLocRhs, elem, vCornerCoords, PT_INSTATIONARY);
    1499            0 :                                         locRhs.scale_append(vScaleStiff[t], tmpLocRhs);
    1500              :                                 }
    1501            0 :                                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot compute Rhs.");
    1502              :                         }
    1503              : 
    1504              :                         //      send local to global rhs
    1505              :                                 try{
    1506            0 :                                         spAssTuner->add_local_vec_to_global(rhs, locRhs, dd);
    1507              :                                 }
    1508            0 :                                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot add local vector.");
    1509              :                 }
    1510              : 
    1511              :         //      finish element loop
    1512              :                 try
    1513              :                 {
    1514            0 :                         Eval.finish_elem_loop();
    1515              :                 }
    1516            0 :                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot finish element loop.");
    1517              : 
    1518              :                 }
    1519            0 :                 UG_CATCH_THROW("(instationary) AssembleRhs: Cannot create Data Evaluator.");
    1520              :         }
    1521              : 
    1522              : // //////////////////////////////////////////////////////////////////////////////
    1523              : // Prepare Timestep (for instationary problems)
    1524              : // /////////////////////////////////////////////////////////////////////////////
    1525              : public:
    1526              :         /**
    1527              :          * This function prepares the global discretization for a time-stepping scheme
    1528              :          * by calling the "prepare_timestep" methods of all passed element
    1529              :          * discretizations.
    1530              :          *
    1531              :          * \param[in]           vElemDisc               element discretizations
    1532              :          * \param[in]           dd                              DoF Distribution
    1533              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1534              :          * \param[in]           vSol                    current and previous solutions
    1535              :          * \param[in]           spAssTuner              assemble adapter
    1536              :          */
    1537              :         static void
    1538            0 :         PrepareTimestep
    1539              :         (
    1540              :                 const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1541              :                 ConstSmartPtr<DoFDistribution> dd,
    1542              :                 bool bNonRegularGrid,
    1543              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1544              :                 number future_time,
    1545              :                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner
    1546              :         )
    1547              :         {
    1548              :         //      get current time and vector
    1549            0 :                 const vector_type& u = *vSol->solution(0);
    1550              : 
    1551              :         //      create local time series
    1552              :                 LocalVectorTimeSeries locTimeSeries;
    1553            0 :                 locTimeSeries.read_times(vSol);
    1554              : 
    1555              :                 try
    1556              :                 {
    1557            0 :                         DataEvaluator<domain_type> Eval(NONE,
    1558              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1559              :                                                    &locTimeSeries);
    1560            0 :                         Eval.set_time_point(0);
    1561              : 
    1562              :                 //      prepare timestep
    1563              :                         try
    1564              :                         {
    1565              :                                 VectorProxy<vector_type> vp(u);
    1566            0 :                                 size_t algebra_index = bridge::AlgebraTypeIDProvider::instance().id<algebra_type>();
    1567            0 :                                 Eval.prepare_timestep(future_time, vSol->time(0), &vp, algebra_index);
    1568              :                         }
    1569            0 :                         UG_CATCH_THROW("(instationary) PrepareTimestep: Cannot prepare timestep.");
    1570              : 
    1571              :                 }
    1572            0 :                 UG_CATCH_THROW("(instationary) PrepareTimestep: Cannot create Data Evaluator.");
    1573            0 :         }
    1574              : 
    1575              : ////////////////////////////////////////////////////////////////////////////////
    1576              : // Prepare Timestep Elem (for instationary problems)
    1577              : ////////////////////////////////////////////////////////////////////////////////
    1578              : public:
    1579              :         /**
    1580              :          * This function prepares the global discretization for a time-stepping scheme
    1581              :          * by calling the "prepare_timestep_elem" methods of all passed element
    1582              :          * discretizations on one given subset.
    1583              :          * (This version processes elements in a given interval.)
    1584              :          *
    1585              :          * \param[in]           vElemDisc               element discretizations
    1586              :          * \param[in]           spDomain                domain
    1587              :          * \param[in]           dd                              DoF Distribution
    1588              :          * \param[in]           iterBegin               element iterator
    1589              :          * \param[in]           iterEnd                 element iterator
    1590              :          * \param[in]           si                              subset index
    1591              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1592              :          * \param[in]           vSol                    current and previous solutions
    1593              :          * \param[in]           spAssTuner              assemble adapter
    1594              :          */
    1595              :         template <typename TElem, typename TIterator>
    1596              :         static void
    1597            0 :         PrepareTimestepElem(const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1598              :                                         ConstSmartPtr<domain_type> spDomain,
    1599              :                                         ConstSmartPtr<DoFDistribution> dd,
    1600              :                                         TIterator iterBegin,
    1601              :                                         TIterator iterEnd,
    1602              :                                         int si, bool bNonRegularGrid,
    1603              :                                         ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1604              :                                         ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
    1605              :         {
    1606              :         //      check if there are any elements at all, otherwise return immediately
    1607            0 :                 if(iterBegin == iterEnd) return;
    1608              : 
    1609              :         //      reference object id
    1610              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1611              : 
    1612              :         //      storage for corner coordinates
    1613            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1614              : 
    1615              :         //      get current time and vector
    1616            0 :                 const vector_type& u = *vSol->solution(0);
    1617              : 
    1618              :         //      create local time series
    1619              :                 LocalVectorTimeSeries locTimeSeries;
    1620            0 :                 locTimeSeries.read_times(vSol);
    1621              : 
    1622              :                 try
    1623              :                 {
    1624            0 :                 DataEvaluator<domain_type> Eval(NONE,
    1625              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1626              :                                                    &locTimeSeries);
    1627            0 :                 Eval.set_time_point(0);
    1628              : 
    1629              :         //      prepare element loop
    1630            0 :                 Eval.prepare_elem_loop(id, si);
    1631              : 
    1632              :         //      local algebra
    1633              :                 LocalIndices ind; LocalVector locU;
    1634              : 
    1635              :         //      Loop over all elements
    1636            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1637              :                 {
    1638              :                 //      get Element
    1639            0 :                         TElem* elem = *iter;
    1640              : 
    1641              :                 //      get corner coordinates
    1642            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1643              : 
    1644              :                 //      check if elem is skipped from assembling
    1645            0 :                         if(!spAssTuner->element_used(elem)) continue;
    1646              : 
    1647              :                 //      get global indices
    1648            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1649              : 
    1650              :                 //      adapt local algebra
    1651            0 :                         locU.resize(ind);
    1652              : 
    1653              :                 //      read local values of u
    1654            0 :                         GetLocalVector(locU, u);
    1655              : 
    1656              :                 //      read local values of time series
    1657            0 :                         if(Eval.time_series_needed())
    1658            0 :                                 locTimeSeries.read_values(vSol, ind);
    1659              : 
    1660              :                 //      prepare timestep
    1661              :                         try
    1662              :                         {
    1663            0 :                                 Eval.prepare_timestep_elem(vSol->time(0), locU, elem, vCornerCoords);
    1664              :                         }
    1665            0 :                         UG_CATCH_THROW("(instationary) PrepareTimestep: Cannot prepare timestep.");
    1666              :                 }
    1667              : 
    1668              :         //      finish element loop
    1669              :                 try
    1670              :                 {
    1671            0 :                         Eval.finish_elem_loop();
    1672              :                 }
    1673            0 :                 UG_CATCH_THROW("AssembleMassMatrix: Cannot finish element loop.");
    1674              :                 
    1675              :                 }
    1676            0 :                 UG_CATCH_THROW("(instationary) PrepareTimestep: Cannot create Data Evaluator.");
    1677              :         }
    1678              : 
    1679              : // //////////////////////////////////////////////////////////////////////////////
    1680              : // Finish Timestep (for instationary problems)
    1681              : // /////////////////////////////////////////////////////////////////////////////
    1682              : public:
    1683              :         /**
    1684              :          * This function finishes the global discretization for a time-stepping scheme
    1685              :          * by calling the "finish_timestep" methods of all passed element
    1686              :          * discretizations.
    1687              :          *
    1688              :          * \param[in]           vElemDisc               element discretizations
    1689              :          * \param[in]           dd                              DoF Distribution
    1690              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1691              :          * \param[in]           vSol                    current and previous solutions
    1692              :          * \param[in]           spAssTuner              assemble adapter
    1693              :          */
    1694              :         static void
    1695            0 :         FinishTimestep
    1696              :         (
    1697              :                 const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1698              :                 ConstSmartPtr<DoFDistribution> dd,
    1699              :                 bool bNonRegularGrid,
    1700              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1701              :                 ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner
    1702              :         )
    1703              :         {
    1704              :         //      get current time and vector
    1705            0 :                 const vector_type& u = *vSol->solution(0);
    1706              : 
    1707              :         //      create local time series
    1708              :                 LocalVectorTimeSeries locTimeSeries;
    1709            0 :                 locTimeSeries.read_times(vSol);
    1710              : 
    1711              :                 try
    1712              :                 {
    1713            0 :                         DataEvaluator<domain_type> Eval(NONE,
    1714              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1715              :                                                    &locTimeSeries);
    1716            0 :                         Eval.set_time_point(0);
    1717              : 
    1718              :                 //      finish time step
    1719              :                         try
    1720              :                         {
    1721              :                                 VectorProxy<vector_type> vp(u);
    1722            0 :                                 size_t algebra_index = bridge::AlgebraTypeIDProvider::instance().id<algebra_type>();
    1723            0 :                                 Eval.finish_timestep(vSol->time(0), &vp, algebra_index);
    1724              :                         }
    1725            0 :                         UG_CATCH_THROW("(instationary) FinishTimestep: Cannot prepare time step.");
    1726              : 
    1727              :                 }
    1728            0 :                 UG_CATCH_THROW("(instationary) FinishTimestep: Cannot create Data Evaluator.");
    1729            0 :         }
    1730              : 
    1731              : ////////////////////////////////////////////////////////////////////////////////
    1732              : // Finish Timestep Elem (for instationary problems)
    1733              : ////////////////////////////////////////////////////////////////////////////////
    1734              : 
    1735              : public:
    1736              :         /**
    1737              :          * This function finalizes the global discretization in a time-stepping scheme
    1738              :          * by calling the "finish_timestep_elem" methods of all passed element
    1739              :          * discretizations on one given subset.
    1740              :          * (This version processes elements in a given interval.)
    1741              :          *
    1742              :          * \param[in]           vElemDisc               element discretizations
    1743              :          * \param[in]           dd                              DoF Distribution
    1744              :          * \param[in]           iterBegin               element iterator
    1745              :          * \param[in]           iterEnd                 element iterator
    1746              :          * \param[in]           si                              subset index
    1747              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1748              :          * \param[in]           vSol                    current and previous solutions
    1749              :          * \param[in]           spAssTuner              assemble adapter
    1750              :          */
    1751              :         template <typename TElem, typename TIterator>
    1752              :         static void
    1753            0 :         FinishTimestepElem(const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1754              :                                    ConstSmartPtr<domain_type> spDomain,
    1755              :                                    ConstSmartPtr<DoFDistribution> dd,
    1756              :                                    TIterator iterBegin,
    1757              :                                    TIterator iterEnd,
    1758              :                                    int si, bool bNonRegularGrid,
    1759              :                                    ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
    1760              :                                    ConstSmartPtr<AssemblingTuner<TAlgebra> > spAssTuner)
    1761              :         {
    1762              :         //      check if there are any elements at all, otherwise return immediately
    1763            0 :                 if(iterBegin == iterEnd) return;
    1764              : 
    1765              :         //      reference object id
    1766              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1767              : 
    1768              :         //      storage for corner coordinates
    1769            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1770              : 
    1771              :         //      get current time and vector
    1772            0 :                 const vector_type& u = *vSol->solution(0);
    1773              : 
    1774              :         //      create local time series
    1775              :                 LocalVectorTimeSeries locTimeSeries;
    1776            0 :                 locTimeSeries.read_times(vSol);
    1777              : 
    1778              :         //      prepare for given elem discs
    1779              :                 try
    1780              :                 {
    1781            0 :                 DataEvaluator<domain_type> Eval(NONE,
    1782              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1783              :                                                    &locTimeSeries);
    1784            0 :                 Eval.set_time_point(0);
    1785              : 
    1786              :         //      prepare loop
    1787            0 :                 Eval.prepare_elem_loop(id, si);
    1788              : 
    1789              :         //      local algebra
    1790              :                 LocalIndices ind; LocalVector locU;
    1791              : 
    1792              :         //      Loop over all elements
    1793            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1794              :                 {
    1795              :                 //      get Element
    1796            0 :                         TElem* elem = *iter;
    1797              : 
    1798              :                 //      get corner coordinates
    1799            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1800              : 
    1801              :                 //      check if elem is skipped from assembling
    1802            0 :                         if(!spAssTuner->element_used(elem)) continue;
    1803              : 
    1804              :                 //      get global indices
    1805            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1806              : 
    1807              :                 //      adapt local algebra
    1808            0 :                         locU.resize(ind);
    1809              : 
    1810              :                 //      read local values of u
    1811            0 :                         GetLocalVector(locU, u);
    1812              : 
    1813              :                 //      read local values of time series
    1814            0 :                         if(Eval.time_series_needed())
    1815            0 :                                 locTimeSeries.read_values(vSol, ind);
    1816              : 
    1817              :                 //      finish timestep
    1818              :                         try
    1819              :                         {
    1820            0 :                                 Eval.finish_timestep_elem(locTimeSeries.time(0), locU, elem, vCornerCoords);
    1821              :                         }
    1822            0 :                         UG_CATCH_THROW("(instationary) FinishTimestepElem: Cannot finish timestep.");
    1823              :                 }
    1824              : 
    1825              :         //      finish element loop
    1826              :                 try
    1827              :                 {
    1828            0 :                         Eval.finish_elem_loop();
    1829              :                 }
    1830            0 :                 UG_CATCH_THROW("AssembleMassMatrix: Cannot finish element loop.");
    1831              :                 
    1832              :                 }
    1833            0 :                 UG_CATCH_THROW("(instationary) FinishTimestepElem: Cannot create Data Evaluator");
    1834              :         }
    1835              : 
    1836              : ////////////////////////////////////////////////////////////////////////////////
    1837              : // Init. all exports (an optional operation, to use the exports for plotting etc.)
    1838              : ////////////////////////////////////////////////////////////////////////////////
    1839              : 
    1840              : public:
    1841              :         /**
    1842              :          * This function finalizes the global discretization in a time-stepping scheme
    1843              :          * by calling the "finish_timestep_elem" methods of all passed element
    1844              :          * discretizations on one given subset.
    1845              :          * (This version processes elements in a given interval.)
    1846              :          *
    1847              :          * \param[in]           vElemDisc               element discretizations
    1848              :          * \param[in]           dd                              DoF Distribution
    1849              :          * \param[in]           iterBegin               element iterator
    1850              :          * \param[in]           iterEnd                 element iterator
    1851              :          * \param[in]           si                              subset index
    1852              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1853              :          * \param[in]           bAsTimeDependent flag to simulate the instationary case for the initialization
    1854              :          */
    1855              :         template <typename TElem, typename TIterator>
    1856              :         static void
    1857            0 :         InitAllExports(const std::vector<IElemDisc<domain_type>*>& vElemDisc,
    1858              :                                    ConstSmartPtr<DoFDistribution> dd,
    1859              :                                    TIterator iterBegin,
    1860              :                                    TIterator iterEnd,
    1861              :                                    int si, bool bNonRegularGrid, bool bAsTimeDependent)
    1862              :         {
    1863              :         //      check if there are any elements at all, otherwise return immediately
    1864            0 :                 if(iterBegin == iterEnd) return;
    1865              : 
    1866              :         //      reference object id
    1867              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1868              : 
    1869              :         //      dummy local time series (only to simulate the instationary case for the initialization)
    1870              :                 LocalVectorTimeSeries locTimeSeries;
    1871              :                 
    1872              :         //      prepare for given elem discs
    1873              :                 try
    1874              :                 {
    1875            0 :                 DataEvaluator<domain_type> Eval(MASS | STIFF | RHS,
    1876              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid,
    1877              :                                                    bAsTimeDependent? &locTimeSeries : NULL);
    1878            0 :                 Eval.set_time_point(0);
    1879              : 
    1880              :         //      prepare loop
    1881            0 :                 Eval.prepare_elem_loop(id, si);
    1882              : 
    1883              : 
    1884              :         //      finish element loop
    1885            0 :                 Eval.finish_elem_loop();
    1886              :                 
    1887              :                 }
    1888            0 :                 UG_CATCH_THROW("InitAllExports: Data Evaluator failed");
    1889              :         }
    1890              : 
    1891              : ////////////////////////////////////////////////////////////////////////////////
    1892              : // Error estimator (stationary)
    1893              : ////////////////////////////////////////////////////////////////////////////////
    1894              : 
    1895              : public:
    1896              :         /**
    1897              :          * This function assembles the error estimator associated with all the
    1898              :          * element discretizations in the internal data structure for one given subset.
    1899              :          * (This version processes elements in a given interval.)
    1900              :          *
    1901              :          * \param[in]           vElemDisc               element discretizations
    1902              :          * \param[in]           spDomain                domain
    1903              :          * \param[in]           dd                              DoF Distribution
    1904              :          * \param[in]           iterBegin               element iterator
    1905              :          * \param[in]           iterEnd                 element iterator
    1906              :          * \param[in]           si                              subset index
    1907              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    1908              :          * \param[in]           u                               solution
    1909              :          */
    1910              :         template <typename TElem, typename TIterator>
    1911              :         static void
    1912            0 :         AssembleErrorEstimator
    1913              :         (
    1914              :                 const std::vector<IElemError<domain_type>*>& vElemDisc,
    1915              :                 ConstSmartPtr<domain_type> spDomain,
    1916              :                 ConstSmartPtr<DoFDistribution> dd,
    1917              :                 TIterator iterBegin,
    1918              :                 TIterator iterEnd,
    1919              :                 int si,
    1920              :                 bool bNonRegularGrid,
    1921              :                 const vector_type& u
    1922              :         )
    1923              :         {
    1924              :         //      check if there are any elements at all, otherwise return immediately
    1925            0 :                 if(iterBegin == iterEnd) return;
    1926              : 
    1927              :         //      reference object id
    1928              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    1929              : 
    1930              :         //      storage for corner coordinates
    1931            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    1932              : 
    1933              :         //      prepare for given elem discs
    1934              :                 try
    1935              :                 {
    1936            0 :                 ErrorEvaluator<domain_type> Eval(STIFF | RHS,
    1937              :                                                    vElemDisc, dd->function_pattern(), bNonRegularGrid);
    1938              : 
    1939              :         //      prepare element loop
    1940            0 :                 Eval.prepare_err_est_elem_loop(id, si);
    1941              : 
    1942              :         //      local indices and local algebra
    1943              :                 LocalIndices ind; LocalVector locU;
    1944              : 
    1945              :         //      Loop over all elements
    1946            0 :                 for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
    1947              :                 {
    1948              :                 //      get Element
    1949              :                         TElem* elem = *iter;
    1950              : 
    1951              :                 //      get corner coordinates
    1952            0 :                         FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    1953              : 
    1954              :                 //      get global indices
    1955            0 :                         dd->indices(elem, ind, Eval.use_hanging());
    1956              : 
    1957              :                 //      adapt local algebra
    1958            0 :                         locU.resize(ind);
    1959              : 
    1960              :                 //      read local values of u
    1961            0 :                         GetLocalVector(locU, u);
    1962              : 
    1963              :                 //      prepare element
    1964              :                         try
    1965              :                         {
    1966            0 :                                 Eval.prepare_err_est_elem(locU, elem, vCornerCoords, ind, false);
    1967              :                         }
    1968            0 :                         UG_CATCH_THROW("(stationary) AssembleRhs: Cannot prepare element.");
    1969              : 
    1970              :                 //      assemble stiffness part
    1971              :                         try
    1972              :                         {
    1973            0 :                                 Eval.compute_err_est_A_elem(locU, elem, vCornerCoords, ind);
    1974              :                         }
    1975            0 :                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot assemble the error estimator for stiffness part.");
    1976              : 
    1977              :                 //      assemble rhs part
    1978              :                         try
    1979              :                         {
    1980            0 :                                 Eval.compute_err_est_rhs_elem(elem, vCornerCoords, ind);
    1981              :                         }
    1982            0 :                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot assemble the error estimator for stiffness part.");
    1983              : 
    1984              :                 }
    1985              : 
    1986              :         //      finish element loop
    1987              :                 try
    1988              :                 {
    1989            0 :                         Eval.finish_err_est_elem_loop();
    1990              :                 }
    1991            0 :                 UG_CATCH_THROW("AssembleErrorEstimator: Cannot finish element loop.");
    1992              : 
    1993              :                 }
    1994            0 :                 UG_CATCH_THROW("AssembleErrorEstimator: Cannot create Data Evaluator.");
    1995              :         }
    1996              : 
    1997              : ////////////////////////////////////////////////////////////////////////////////
    1998              : // Error estimator (for time-dependent problems)
    1999              : ////////////////////////////////////////////////////////////////////////////////
    2000              : 
    2001              : public:
    2002              :         /**
    2003              :          * This function assembles the error estimator associated with all the
    2004              :          * element discretizations in the internal data structure for one given subset.
    2005              :          * (This version processes elements in a given interval.)
    2006              :          *
    2007              :          * \param[in]           vElemDisc               element discretizations
    2008              :          * \param[in]           spDomain                domain
    2009              :          * \param[in]           dd                              DoF Distribution
    2010              :          * \param[in]           iterBegin               element iterator
    2011              :          * \param[in]           iterEnd                 element iterator
    2012              :          * \param[in]           si                              subset index
    2013              :          * \param[in]           bNonRegularGrid flag to indicate if non regular grid is used
    2014              :          * \param[in]           vScaleMass              scaling factors for mass part
    2015              :          * \param[in]           vScaleStiff             scaling factors for stiffness part
    2016              :          * \param[in]           vSol                            solution
    2017              :          */
    2018              :         template <typename TElem, typename TIterator>
    2019              :         static void
    2020            0 :         AssembleErrorEstimator
    2021              :         (
    2022              :                 const std::vector<IElemError<domain_type>*>& vElemDisc,
    2023              :                 ConstSmartPtr<domain_type> spDomain,
    2024              :                 ConstSmartPtr<DoFDistribution> dd,
    2025              :                 TIterator iterBegin,
    2026              :                 TIterator iterEnd,
    2027              :                 int si,
    2028              :                 bool bNonRegularGrid,
    2029              :                 const std::vector<number>& vScaleMass,
    2030              :                 const std::vector<number>& vScaleStiff,
    2031              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol
    2032              :         )
    2033              :         {
    2034              :         //      check if there are any elements at all, otherwise return immediately
    2035            0 :                 if (iterBegin == iterEnd) return;
    2036              : 
    2037              :         //      reference object id
    2038              :                 static const ReferenceObjectID id = geometry_traits<TElem>::REFERENCE_OBJECT_ID;
    2039              : 
    2040              :         //      storage for corner coordinates
    2041            0 :                 MathVector<domain_type::dim> vCornerCoords[TElem::NUM_VERTICES];
    2042              : 
    2043              :         //      check time scheme
    2044            0 :                 if(vScaleMass.size() != vScaleStiff.size())
    2045            0 :                         UG_THROW("(instationary) AssembleErrorEstimator: s_a and s_m must have same size.");
    2046              : 
    2047            0 :                 if(vSol->size() < vScaleStiff.size())
    2048            0 :                         UG_THROW("(instationary) AssembleErrorEstimator: Time stepping scheme needs at "
    2049              :                                         "least "<<vScaleStiff.size()<<" time steps, but only "<<
    2050              :                                         vSol->size() << " passed.");
    2051              : 
    2052              :         //      create local time series
    2053              :                 LocalVectorTimeSeries locTimeSeries;
    2054            0 :                 locTimeSeries.read_times(vSol);
    2055              : 
    2056              :         //      prepare for given elem discs
    2057              :                 try
    2058              :                 {
    2059            0 :                         ErrorEvaluator<domain_type> Eval(MASS | STIFF | RHS,
    2060              :                                                            vElemDisc, dd->function_pattern(), bNonRegularGrid,
    2061              :                                                            &locTimeSeries, &vScaleMass, &vScaleStiff);
    2062              : 
    2063              :                 //      prepare element loop
    2064            0 :                         Eval.prepare_err_est_elem_loop(id, si);
    2065              : 
    2066              :                 //      local indices and local algebra
    2067              :                         LocalIndices ind;
    2068              : 
    2069              :                 //      loop over all elements
    2070            0 :                         for (TIterator iter = iterBegin; iter != iterEnd; ++iter)
    2071              :                         {
    2072              :                         //      get Element
    2073              :                                 TElem* elem = *iter;
    2074              : 
    2075              :                         //      get corner coordinates
    2076            0 :                                 FillCornerCoordinates(vCornerCoords, *elem, *spDomain);
    2077              : 
    2078              :                         //      get global indices
    2079            0 :                                 dd->indices(elem, ind, Eval.use_hanging());
    2080              : 
    2081              :                         //      read local values of time series
    2082            0 :                                 locTimeSeries.read_values(vSol, ind);
    2083              : 
    2084              :                         //      loop all time points and assemble them
    2085            0 :                                 for (std::size_t t = 0; t < vScaleStiff.size(); ++t)
    2086              :                                 {
    2087              :                                 //      get local solution at timepoint
    2088              :                                         LocalVector& locU = locTimeSeries.solution(t);
    2089            0 :                                         Eval.set_time_point(t);
    2090              : 
    2091              :                                 //      prepare element
    2092              :                                         try
    2093              :                                         {
    2094            0 :                                                 Eval.prepare_err_est_elem(locU, elem, vCornerCoords, ind, false);
    2095              :                                         }
    2096            0 :                                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot prepare element.");
    2097              : 
    2098              :                                 //      assemble stiffness part
    2099              :                                         try
    2100              :                                         {
    2101            0 :                                                 Eval.compute_err_est_A_elem(locU, elem, vCornerCoords, ind, vScaleMass[t], vScaleStiff[t]);
    2102              :                                         }
    2103            0 :                                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot assemble the error estimator for stiffness part.");
    2104              : 
    2105              :                                 //      assemble mass part
    2106              :                                         try
    2107              :                                         {
    2108            0 :                                                 Eval.compute_err_est_M_elem(locU, elem, vCornerCoords, ind, vScaleMass[t], vScaleStiff[t]);
    2109              :                                         }
    2110            0 :                                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot assemble the error estimator for stiffness part.");
    2111              : 
    2112              :                                 //      assemble rhs part
    2113              :                                         try
    2114              :                                         {
    2115            0 :                                                 Eval.compute_err_est_rhs_elem(elem, vCornerCoords, ind, vScaleMass[t], vScaleStiff[t]);
    2116              :                                         }
    2117            0 :                                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot assemble the error estimator for stiffness part.");
    2118              :                                 }
    2119              :                         }
    2120              : 
    2121              :                         //      finish element loop
    2122              :                         try
    2123              :                         {
    2124            0 :                                 Eval.finish_err_est_elem_loop();
    2125              :                         }
    2126            0 :                         UG_CATCH_THROW("AssembleErrorEstimator: Cannot finish element loop.");
    2127              : 
    2128              :                 }
    2129            0 :                 UG_CATCH_THROW("AssembleErrorEstimator: Cannot create Data Evaluator.");
    2130              :         }
    2131              : 
    2132              : }; // class StdGlobAssembler
    2133              : 
    2134              : } // end namespace ug
    2135              : 
    2136              : 
    2137              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__ELEM_DISC__ELEM_DISC_ASSEMBLE_UTIL__ */
        

Generated by: LCOV version 2.0-1