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

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__
      34              : #define __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__
      35              : 
      36              : #include "lib_disc/spatial_disc/constraints/continuity_constraints/p1_continuity_constraints.h"
      37              : #include "lib_disc/domain.h"
      38              : 
      39              : namespace ug {
      40              : 
      41              : ///     sets a matrix row corresponding to averaging the constrained index
      42              : template <typename TMatrix>
      43            0 : void SetInterpolation(TMatrix& A,
      44              :                       std::vector<size_t> & constrainedIndex,
      45              :                       std::vector<std::vector<size_t> >& vConstrainingIndex,
      46              :                                           bool assembleLinearProblem = true)
      47              : {
      48              :         //typedef typename TMatrix::row_iterator row_iterator;
      49              :         //typedef typename TMatrix::value_type block_type;
      50              : 
      51              :         //      check number of indices passed
      52              :         for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
      53              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
      54              :                                   "Wrong number of indices.");
      55              : 
      56              : //      loop all constrained dofs
      57            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
      58              :         {
      59            0 :                 const size_t ai = constrainedIndex[i];
      60              : 
      61              :         //      remove all couplings
      62            0 :                 SetRow(A, ai, 0.0);
      63              : 
      64              :         //      set diag of row to identity
      65            0 :                 A(ai, ai) = 1.0;
      66              : 
      67              :         //      set coupling to all constraining dofs the inverse of the
      68              :         //      number of constraining dofs
      69              :         //      This is only required if assembling for a linear problem.
      70            0 :                 if (assembleLinearProblem)
      71              :                 {
      72            0 :                         const number frac = -1.0/(vConstrainingIndex.size());
      73            0 :                         for(size_t j=0; j < vConstrainingIndex.size(); ++j)
      74            0 :                                 A(ai, vConstrainingIndex[j][i]) = frac;
      75              :                 }
      76              :         }
      77            0 : }
      78              : 
      79              : template <typename TVector>
      80            0 : void InterpolateValues(TVector& u,
      81              :                        std::vector<size_t>& constrainedIndex,
      82              :                        std::vector<std::vector<size_t> >& vConstrainingIndex)
      83              : {
      84              :         typedef typename TVector::value_type block_type;
      85              : 
      86              :         //      check number of indices passed
      87            0 :         for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
      88              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
      89              :                                   "Wrong number of indices.");
      90              : 
      91              : //      scaling factor
      92            0 :         const number frac = 1./(vConstrainingIndex.size());
      93              : 
      94              : //      loop constrained indices
      95            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
      96              :         {
      97              :         //      get value to be interpolated
      98            0 :                 block_type& val = u[constrainedIndex[i]];
      99              : 
     100              :         //      reset value
     101            0 :                 val = 0.0;
     102              : 
     103              :         //      add equally from all constraining indices
     104            0 :                 for(size_t j=0; j < vConstrainingIndex.size(); ++j)
     105            0 :                         VecScaleAdd(val, 1.0, val, frac, u[vConstrainingIndex[j][i]]);
     106              :                         //val += frac * u[vConstrainingIndex[j][i]];
     107              :         }
     108            0 : }
     109              : 
     110              : 
     111              : 
     112              : template <typename TMatrix>
     113            0 : void SplitAddRow_Symmetric(TMatrix& A,
     114              :                            std::vector<size_t>& constrainedIndex,
     115              :                            std::vector<std::vector<size_t> >& vConstrainingIndex)
     116              : {
     117              :         typedef typename TMatrix::value_type block_type;
     118              :         typedef typename TMatrix::row_iterator row_iterator;
     119              : 
     120              :         size_t nConstrg = vConstrainingIndex.size();
     121              :         UG_ASSERT(nConstrg, "There have to be constraining indices!");
     122              : 
     123              :         //      check number of indices passed
     124              :         for(size_t i = 0; i < nConstrg; ++i)
     125              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
     126              :                                   "Wrong number of indices.");
     127              : 
     128              : //      scaling factor
     129            0 :         const number frac = 1.0 / nConstrg;
     130              : 
     131              : //      handle each constrained index
     132            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
     133              :         {
     134            0 :                 const size_t algInd = constrainedIndex[i];
     135              : 
     136              :         //      add coupling constrained index -> constrained index
     137              :         //      we don't have to adjust the block itself, since the row of
     138              :         //      constraints will be set to interpolation afterwards
     139            0 :                 block_type diagEntry = A(algInd, algInd);
     140              : 
     141              :         //      scale by weight
     142            0 :                 diagEntry *= frac*frac;
     143              : 
     144              :         //      add coupling constrained dof -> constrained dof
     145            0 :                 for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
     146            0 :                         for(size_t m = 0; m < vConstrainingIndex.size(); ++m)
     147            0 :                                 A(vConstrainingIndex[k][i], vConstrainingIndex[m][i]) += diagEntry;
     148              : 
     149              : #if 0
     150              : 
     151              :                 // (handled separately as it would otherwise trigger an assert -
     152              :                 // manipulation of matrix row while iterating over it)
     153              :                 const block_type block = A(algInd, algInd);
     154              :                 size_t nBlockCols = GetCols(block);
     155              :                 UG_ASSERT(nBlockCols == constrainedIndex.size(),
     156              :                         "Number of block cols and number of constrained DoFs in hanging vertex not equal.");
     157              :                 for (size_t blockIndConn = 0; blockIndConn < nBlockCols; ++blockIndConn)
     158              :                 {
     159              :                         const number val = BlockRef(block, blockInd, blockIndConn) * frac*frac;
     160              :                         for (size_t k = 0; k < nConstrg; ++k)
     161              :                                 for (size_t m = 0; m < nConstrg; ++m)
     162              :                                         DoFRef(A, vConstrainingIndex[k][i], vConstrainingIndex[m][blockIndConn]) += val;
     163              :                 }
     164              : #endif
     165              : 
     166              :         //      loop coupling between constrained dof -> any other dof
     167            0 :                 for(row_iterator conn = A.begin_row(algInd); conn != A.end_row(algInd); ++conn)
     168              :                 {
     169              :                         const size_t algIndConn = conn.index();
     170              : 
     171              :                         // diagonal entry already handled
     172            0 :                         if (algIndConn == algInd)
     173            0 :                                 continue;
     174              : 
     175              :                         // warning: do NOT use references here!
     176              :                         // they might become invalid when A is accessed at an entry that does not exist yet
     177              :                         // FIXME: This will only work properly if there is an entry A(i,j) for any entry
     178              :                         //        A(j,i) in the matrix! Is this always the case!?
     179            0 :                         block_type block = conn.value();
     180            0 :                         block_type blockT = A(algIndConn, algInd);
     181              : 
     182              :                 //      multiply the cpl value by the inverse number of constraining
     183            0 :                         block *= frac;
     184            0 :                         blockT *= frac;
     185              : 
     186              :                 //      add the coupling to the constraining indices rows
     187            0 :                         for (size_t k = 0; k < nConstrg; ++k)
     188              :                         {
     189              :                                 UG_ASSERT(vConstrainingIndex[k][i] != constrainedIndex[i],
     190              :                                                 "Modifying 'this' (=conn referenced) matrix row is invalid!" << constrainedIndex[i]);
     191            0 :                                 A(vConstrainingIndex[k][i], algIndConn) += block;
     192            0 :                                 A(algIndConn, vConstrainingIndex[k][i]) += blockT;
     193              :                         }
     194              : 
     195              :                 //      set the split coupling to zero
     196              :                 //      this needs to be done only in columns, since the row associated to
     197              :                 //      the constrained index will be set to unity (or interpolation).
     198            0 :                         A(algIndConn, algInd) = 0.0;
     199              :                 }
     200              :         }
     201            0 : }
     202              : 
     203              : template <typename TMatrix>
     204            0 : void SplitAddRow_OneSide(TMatrix& A,
     205              :                          std::vector<size_t>& constrainedIndex,
     206              :                          std::vector<std::vector<size_t> >& vConstrainingIndex)
     207              : {
     208              :         typedef typename TMatrix::value_type block_type;
     209              :         typedef typename TMatrix::row_iterator row_iterator;
     210              : 
     211              :         UG_ASSERT(!vConstrainingIndex.empty(), "There have to be constraining indices!");
     212              : 
     213              :         //      check number of indices passed
     214            0 :         for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
     215              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
     216              :                                   "Wrong number of indices.");
     217              : 
     218              : //      scaling factor
     219            0 :         const number frac = 1./(vConstrainingIndex.size());
     220              : 
     221            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
     222              :         {
     223            0 :                 const size_t algInd = constrainedIndex[i];
     224              : 
     225              :         // choose randomly the first dof to add whole row
     226            0 :                 const size_t addTo = vConstrainingIndex[0][i];
     227              : 
     228            0 :                 block_type diagEntry = A(algInd, algInd);
     229              : 
     230              :         //      scale by weight
     231            0 :                 diagEntry *= frac;
     232              : 
     233              :         //      add coupling
     234            0 :                 for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
     235            0 :                         A(addTo, vConstrainingIndex[k][i]) += diagEntry;
     236              : 
     237              :         //      loop coupling between constrained dof -> any other dof
     238            0 :                 for(row_iterator conn = A.begin_row(algInd); conn != A.end_row(algInd); ++conn)
     239              :                 {
     240              :                         const size_t algIndConn = conn.index();
     241              : 
     242              :                         //      skip self-coupling (already handled)
     243            0 :                         if (algIndConn == algInd) continue;
     244              : 
     245              :                         // warning: do NOT use references here!
     246              :                         // they might become invalid when A is accessed at an entry that does not exist yet
     247              :                         // FIXME: This will only work properly if there is an entry A(i,j) for any entry
     248              :                         //        A(j,i) in the matrix! Is this always the case!?
     249            0 :                         const block_type block = conn.value();
     250            0 :                         block_type blockT = A(algIndConn, algInd);
     251              : 
     252            0 :                         blockT *= frac;
     253              : 
     254              :                 //      add the coupling to the constraining indices rows
     255            0 :                         for(size_t k = 0; k < vConstrainingIndex.size(); ++k)
     256            0 :                                 A(algIndConn, vConstrainingIndex[k][i]) += blockT;
     257              : 
     258              :                 //      coupling due to one side adding
     259            0 :                         A(addTo, algIndConn) += block;
     260              : 
     261              :                 //      set the split coupling to zero
     262              :                 //      this must only be done in columns, since the row associated to
     263              :                 //      the constrained index will be set to an interpolation.
     264            0 :                         A(algIndConn, algInd) = 0.0;
     265              :                 }
     266              :         }
     267            0 : }
     268              : 
     269              : template <typename TVector>
     270            0 : void SplitAddRhs_Symmetric(TVector& rhs,
     271              :                          std::vector<size_t> & constrainedIndex,
     272              :                          std::vector<std::vector<size_t> >& vConstrainingIndex)
     273              : {
     274              :         typedef typename TVector::value_type block_type;
     275              : 
     276              :         //      check number of indices passed
     277            0 :         for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
     278              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
     279              :                                   "Wrong number of indices.");
     280              : 
     281              : //      scaling factor
     282            0 :         const number frac = 1./(vConstrainingIndex.size());
     283              : 
     284              : //      loop constrained indices
     285            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
     286              :         {
     287              :         //      get constrained rhs
     288              :         //      modify block directly since set to zero afterwards
     289            0 :                 block_type& val = rhs[constrainedIndex[i]];
     290            0 :                 val *= frac;
     291              : 
     292              :         //      split equally on all constraining indices
     293            0 :                 for(size_t j=0; j < vConstrainingIndex.size(); ++j)
     294            0 :                         rhs[vConstrainingIndex[j][i]] += val;
     295              : 
     296              :         //      set rhs to zero for constrained index
     297            0 :                 val = 0.0;
     298              :         }
     299            0 : }
     300              : 
     301              : template <typename TVector>
     302            0 : void SplitAddRhs_OneSide(TVector& rhs,
     303              :                        std::vector<size_t> & constrainedIndex,
     304              :                        std::vector<std::vector<size_t> >& vConstrainingIndex)
     305              : {
     306              :         typedef typename TVector::value_type block_type;
     307              : 
     308              :         //      check number of indices passed
     309            0 :         for(size_t i = 0; i < vConstrainingIndex.size(); ++i)
     310              :                 UG_ASSERT(vConstrainingIndex[i].size() == constrainedIndex.size(),
     311              :                                   "Wrong number of indices.");
     312              : 
     313            0 :         for(size_t i = 0; i < constrainedIndex.size(); ++i)
     314              :         {
     315              :                 // choose randomly the first dof to add whole
     316              :                 // (must be the same as for row)
     317            0 :                 const size_t addTo = vConstrainingIndex[0][i];
     318              : 
     319            0 :                 block_type& val = rhs[constrainedIndex[i]];
     320            0 :                 rhs[addTo] += val;
     321            0 :                 val = 0.0;
     322              :         }
     323            0 : }
     324              : 
     325              : 
     326              : /**
     327              :  * @brief Extract algebra indices for constrained and constraining indices from DoF distribution
     328              :  *
     329              :  * @param dd                DoF distribution
     330              :  * @param hgVrt             the hanging vertex
     331              :  * @param vConstrainingVrt  vector of constraining vertices
     332              :  * @param constrainedInd    vector of algebra indices on hanging vertex
     333              :  * @param vConstrainingInd  vector of (vector of constraining algebra indices) for constraining vertices
     334              :  */
     335            0 : inline void get_algebra_indices(ConstSmartPtr<DoFDistribution> dd,
     336              :                                                  ConstrainedVertex* hgVrt,
     337              :                                                  std::vector<Vertex*>& vConstrainingVrt,
     338              :                                                  std::vector<size_t>& constrainedInd,
     339              :                                                  std::vector<std::vector<size_t> >& vConstrainingInd)
     340              : {
     341              : // get subset index
     342            0 :         const int si = dd->subset_handler()->get_subset_index(hgVrt);
     343              : 
     344              : //      get constraining vertices
     345            0 :         CollectConstraining(vConstrainingVrt, *dd->multi_grid(), hgVrt);
     346              : 
     347              : // clear constrainedInd
     348              :         constrainedInd.clear();
     349              : 
     350              : //      resize constraining indices
     351              :         vConstrainingInd.clear();
     352            0 :         vConstrainingInd.resize(vConstrainingVrt.size());
     353              : 
     354            0 :         if (dd->grouped())  // block algebra (assuming constrainers have exactly the same functions as constrained)
     355              :         {
     356              :         //      get indices for constrained vertex
     357            0 :                 dd->inner_algebra_indices(hgVrt, constrainedInd, false);
     358              : 
     359              :         //      get indices for constraining vertices
     360            0 :                 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
     361            0 :                         dd->inner_algebra_indices(vConstrainingVrt[i], vConstrainingInd[i], false);
     362              :         }
     363              :         else  // scalar algebra
     364              :         {
     365              :         //      get algebra indices for constrained and constraining vertices
     366            0 :                 for (size_t fct = 0; fct < dd->num_fct(); ++fct)
     367              :                 {
     368              :                 //      check that function is defined on subset
     369            0 :                         if (!dd->is_def_in_subset(fct, si)) continue;
     370              : 
     371              :                 //      get indices for constrained vertex
     372            0 :                         dd->inner_algebra_indices_for_fct(hgVrt, constrainedInd, false, fct);
     373              : 
     374              :                 //      get indices for constraining vertices
     375            0 :                         for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
     376              :                         {
     377            0 :                                 const int siC = dd->subset_handler()->get_subset_index(vConstrainingVrt[i]);
     378              : 
     379              :                         //      check that function is defined on subset
     380            0 :                                 UG_COND_THROW(!dd->is_def_in_subset(fct, siC),
     381              :                                         "Function " << fct << " is defined for a constrained vertex, "
     382              :                                         "but not for one of its constraining vertices!");
     383              : 
     384            0 :                                 dd->inner_algebra_indices_for_fct(vConstrainingVrt[i], vConstrainingInd[i], false, fct);
     385              :                         }
     386              :                 }
     387              :         }
     388            0 : }
     389              : 
     390              : ////////////////////////////////////////////////////////////////////////////////
     391              : ////////////////////////////////////////////////////////////////////////////////
     392              : //      Sym P1 Constraints
     393              : ////////////////////////////////////////////////////////////////////////////////
     394              : ////////////////////////////////////////////////////////////////////////////////
     395              : 
     396              : template <typename TDomain, typename TAlgebra>
     397              : void
     398            0 : SymP1Constraints<TDomain,TAlgebra>::
     399              : adjust_defect(vector_type& d, const vector_type& u,
     400              :               ConstSmartPtr<DoFDistribution> dd, int type, number time,
     401              :               ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     402              :                           const std::vector<number>* vScaleMass,
     403              :                           const std::vector<number>* vScaleStiff)
     404              : {
     405            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     406            0 :                 UG_THROW("index-wise assemble routine is not "
     407              :                                 "implemented for SymP1Constraints \n");
     408              : 
     409              : //      storage for indices and vertices
     410              :         std::vector<std::vector<size_t> > vConstrainingInd;
     411              :         std::vector<size_t> constrainedInd;
     412              :         std::vector<Vertex*> vConstrainingVrt;
     413              : 
     414              : //      get begin end of hanging vertices
     415              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     416            0 :         iter = dd->begin<ConstrainedVertex>();
     417            0 :         iterEnd = dd->end<ConstrainedVertex>();
     418              : 
     419              : //      loop constrained vertices
     420            0 :         for(; iter != iterEnd; ++iter)
     421              :         {
     422              :         //      get hanging vert
     423              :                 ConstrainedVertex* hgVrt = *iter;
     424              : 
     425              :         // get algebra indices for constrained and constraining vertices
     426            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     427              : 
     428              :         //      adapt rhs
     429            0 :                 SplitAddRhs_Symmetric(d, constrainedInd, vConstrainingInd);
     430              :         }
     431            0 : }
     432              : 
     433              : 
     434              : template <typename TDomain, typename TAlgebra>
     435              : void
     436            0 : SymP1Constraints<TDomain,TAlgebra>::
     437              : adjust_rhs(vector_type& rhs, const vector_type& u,
     438              :            ConstSmartPtr<DoFDistribution> dd, int type, number time)
     439              : {
     440            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     441            0 :                 UG_THROW("index-wise assemble routine is not "
     442              :                                 "implemented for SymP1Constraints \n");
     443              : 
     444              : //      storage for indices and vertices
     445              :         std::vector<std::vector<size_t> > vConstrainingInd;
     446              :         std::vector<size_t> constrainedInd;
     447              :         std::vector<Vertex*> vConstrainingVrt;
     448              : 
     449              : //      get begin end of hanging vertices
     450              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     451            0 :         iter = dd->begin<ConstrainedVertex>();
     452            0 :         iterEnd = dd->end<ConstrainedVertex>();
     453              : 
     454              : //      loop constrained vertices
     455            0 :         for(; iter != iterEnd; ++iter)
     456              :         {
     457              :         //      get hanging vert
     458              :                 ConstrainedVertex* hgVrt = *iter;
     459              : 
     460              :         // get algebra indices for constrained and constraining vertices
     461            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     462              : 
     463              :         //      adapt rhs
     464            0 :                 SplitAddRhs_Symmetric(rhs, constrainedInd, vConstrainingInd);
     465              :         }
     466            0 : }
     467              : 
     468              : template <typename TDomain, typename TAlgebra>
     469              : void
     470            0 : SymP1Constraints<TDomain,TAlgebra>::
     471              : adjust_jacobian(matrix_type& J, const vector_type& u,
     472              :                 ConstSmartPtr<DoFDistribution> dd, int type, number time,
     473              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     474              :                                 const number s_a0)
     475              : {
     476            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     477            0 :                 UG_THROW("index-wise assemble routine is not "
     478              :                                 "implemented for SymP1Constraints \n");
     479              : 
     480              : //      storage for indices and vertices
     481              :         std::vector<std::vector<size_t> > vConstrainingInd;
     482              :         std::vector<size_t> constrainedInd;
     483              :         std::vector<Vertex*> vConstrainingVrt;
     484              : 
     485              : //      get begin end of hanging vertices
     486              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     487            0 :         iter = dd->begin<ConstrainedVertex>();
     488            0 :         iterEnd = dd->end<ConstrainedVertex>();
     489              : 
     490              : //      loop constrained vertices
     491            0 :         for(; iter != iterEnd; ++iter)
     492              :         {
     493              :         //      get hanging vert
     494              :                 ConstrainedVertex* hgVrt = *iter;
     495              : 
     496              :         // get algebra indices for constrained and constraining vertices
     497            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     498              : 
     499              :         //      Split using indices
     500            0 :                 SplitAddRow_Symmetric(J, constrainedInd, vConstrainingInd);
     501              : 
     502              :         //      set interpolation
     503            0 :                 SetInterpolation(J, constrainedInd, vConstrainingInd, m_bAssembleLinearProblem);
     504              :         }
     505            0 : }
     506              : 
     507              : template <typename TDomain, typename TAlgebra>
     508              : void
     509            0 : SymP1Constraints<TDomain,TAlgebra>::
     510              : adjust_linear(matrix_type& mat, vector_type& rhs,
     511              :               ConstSmartPtr<DoFDistribution> dd, int type, number time)
     512              : {
     513            0 :         m_bAssembleLinearProblem = true;
     514              : 
     515            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     516            0 :                 UG_THROW("index-wise assemble routine is not "
     517              :                                 "implemented for SymP1Constraints \n");
     518              : 
     519              : //      storage for indices and vertices
     520              :         std::vector<std::vector<size_t> > vConstrainingInd;
     521              :         std::vector<size_t> constrainedInd;
     522              :         std::vector<Vertex*> vConstrainingVrt;
     523              : 
     524              : //      get begin end of hanging vertices
     525              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     526            0 :         iter = dd->begin<ConstrainedVertex>();
     527            0 :         iterEnd = dd->end<ConstrainedVertex>();
     528              : 
     529              : //      loop constrained vertices
     530            0 :         for(; iter != iterEnd; ++iter)
     531              :         {
     532              :         //      get hanging vert
     533              :                 ConstrainedVertex* hgVrt = *iter;
     534              : 
     535              :         // get algebra indices for constrained and constraining vertices
     536            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     537              : 
     538              :         //      Split using indices
     539            0 :                 SplitAddRow_Symmetric(mat, constrainedInd, vConstrainingInd);
     540              : 
     541              :         //      set interpolation
     542            0 :                 SetInterpolation(mat, constrainedInd, vConstrainingInd, true);
     543              : 
     544              :         //      adapt rhs
     545            0 :                 SplitAddRhs_Symmetric(rhs, constrainedInd, vConstrainingInd);
     546              :         }
     547            0 : }
     548              : 
     549              : template <typename TDomain, typename TAlgebra>
     550              : void
     551            0 : SymP1Constraints<TDomain,TAlgebra>::
     552              : adjust_solution(vector_type& u, ConstSmartPtr<DoFDistribution> dd,
     553              :                                 int type, number time)
     554              : {
     555            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     556            0 :                 UG_THROW("index-wise assemble routine is not "
     557              :                                 "implemented for SymP1Constraints \n");
     558              : 
     559              : //      storage for indices and vertices
     560              :         std::vector<std::vector<size_t> > vConstrainingInd;
     561              :         std::vector<size_t> constrainedInd;
     562              :         std::vector<Vertex*> vConstrainingVrt;
     563              : 
     564              : //      get begin end of hanging vertices
     565              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     566            0 :         iter = dd->begin<ConstrainedVertex>();
     567            0 :         iterEnd = dd->end<ConstrainedVertex>();
     568              : 
     569              : //      loop constraining edges
     570            0 :         for(; iter != iterEnd; ++iter)
     571              :         {
     572              :         //      get hanging vert
     573              :                 ConstrainedVertex* hgVrt = *iter;
     574              : 
     575              :         // get algebra indices for constrained and constraining vertices
     576            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     577              : 
     578              :         //      Interpolate values
     579            0 :                 InterpolateValues(u, constrainedInd, vConstrainingInd);
     580              :         }
     581            0 : }
     582              : 
     583              : 
     584              : template <typename TDomain, typename TAlgebra>
     585              : void
     586            0 : SymP1Constraints<TDomain,TAlgebra>::
     587              : adjust_prolongation
     588              : (
     589              :         matrix_type& P,
     590              :         ConstSmartPtr<DoFDistribution> ddFine,
     591              :         ConstSmartPtr<DoFDistribution> ddCoarse,
     592              :         int type,
     593              :         number time
     594              : )
     595              : {
     596            0 :         if (m_bAssembleLinearProblem) return;
     597              : 
     598            0 :         if (this->m_spAssTuner->single_index_assembling_enabled())
     599            0 :                         UG_THROW("index-wise assemble routine is not "
     600              :                                         "implemented for SymP1Constraints \n");
     601              : 
     602              : //      storage for indices and vertices
     603              :         std::vector<std::vector<size_t> > vConstrainingInd;
     604              :         std::vector<size_t> constrainedInd;
     605              :         std::vector<Vertex*> vConstrainingVrt;
     606              : 
     607              : //      get begin end of hanging vertices
     608              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     609            0 :         iter = ddFine->begin<ConstrainedVertex>();
     610            0 :         iterEnd = ddFine->end<ConstrainedVertex>();
     611              : 
     612              : //      loop constrained vertices
     613            0 :         for(; iter != iterEnd; ++iter)
     614              :         {
     615              :         //      get hanging vert
     616              :                 ConstrainedVertex* hgVrt = *iter;
     617              : 
     618              :         // get algebra indices for constrained and constraining vertices
     619            0 :                 get_algebra_indices(ddFine, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     620              : 
     621              :         //      set zero row
     622              :                 size_t sz = constrainedInd.size();
     623            0 :                 for (size_t i = 0; i < sz; ++i)
     624            0 :                         SetRow(P, constrainedInd[i], 0.0);
     625              :         }
     626            0 : }
     627              : 
     628              : 
     629              : template <typename TDomain, typename TAlgebra>
     630              : void
     631            0 : SymP1Constraints<TDomain,TAlgebra>::
     632              : adjust_restriction
     633              : (
     634              :         matrix_type& R,
     635              :         ConstSmartPtr<DoFDistribution> ddCoarse,
     636              :         ConstSmartPtr<DoFDistribution> ddFine,
     637              :         int type,
     638              :         number time
     639              : )
     640              : {
     641              : 
     642            0 : }
     643              : 
     644              : 
     645              : 
     646              : template <typename TDomain, typename TAlgebra>
     647              : void
     648            0 : SymP1Constraints<TDomain,TAlgebra>::
     649              : adjust_correction
     650              : (       vector_type& u,
     651              :         ConstSmartPtr<DoFDistribution> dd,
     652              :         int type,
     653              :         number time
     654              : )
     655              : {
     656              :         //typedef typename vector_type::value_type block_type;
     657              : 
     658            0 :         if (this->m_spAssTuner->single_index_assembling_enabled())
     659            0 :                 UG_THROW("index-wise assemble routine is not "
     660              :                                 "implemented for OneSideP1Constraints \n");
     661              : 
     662              :         // storage for indices and vertices
     663              :         std::vector<std::vector<size_t> > vConstrainingInd;
     664              :         std::vector<size_t>  constrainedInd;
     665              :         std::vector<Vertex*> vConstrainingVrt;
     666              : 
     667              :         // get begin end of hanging vertices
     668              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     669            0 :         iter = dd->begin<ConstrainedVertex>();
     670            0 :         iterEnd = dd->end<ConstrainedVertex>();
     671              : 
     672              :         // loop constrained vertices
     673            0 :         for (; iter != iterEnd; ++iter)
     674              :         {
     675              :                 // get hanging vert
     676              :                 ConstrainedVertex* hgVrt = *iter;
     677              : 
     678              :                 // get algebra indices for constrained and constraining vertices
     679            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     680              : 
     681              :                 // set all entries corresponding to constrained dofs to zero
     682            0 :                 for (size_t i = 0; i < constrainedInd.size(); ++i)
     683            0 :                         u[constrainedInd[i]] = 0.0;
     684              :         }
     685            0 : }
     686              : 
     687              : 
     688              : ////////////////////////////////////////////////////////////////////////////////
     689              : ////////////////////////////////////////////////////////////////////////////////
     690              : //      OneSide P1 Constraints
     691              : ////////////////////////////////////////////////////////////////////////////////
     692              : ////////////////////////////////////////////////////////////////////////////////
     693              : 
     694              : template<int dim>
     695              : struct SortVertexPos {
     696              : 
     697              :                 SortVertexPos(SmartPtr<Domain<dim, MultiGrid, MGSubsetHandler> > spDomain)
     698              :                         : m_aaPos(spDomain->position_accessor())
     699              :                 {}
     700              : 
     701              :                 inline bool operator() (Vertex* vrt1, Vertex* vrt2)
     702              :                         {UG_THROW(dim <<" not implemented.");}
     703              : 
     704              :         protected:
     705              :           typename Domain<dim, MultiGrid, MGSubsetHandler>::position_accessor_type& m_aaPos;
     706              : };
     707              : 
     708              : template<>
     709              : inline bool SortVertexPos<1>::operator() (Vertex* vrt1, Vertex* vrt2)
     710              : {
     711              :         if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
     712              :                 return true;
     713              :         }
     714              :         return false;
     715              : }
     716              : 
     717              : template<>
     718              : inline bool SortVertexPos<2>::operator() (Vertex* vrt1, Vertex* vrt2)
     719              : {
     720              :         if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
     721              :                 return true;
     722              :         }
     723              :         else if(m_aaPos[vrt1][0] == m_aaPos[vrt2][0]) {
     724              :                 if(m_aaPos[vrt1][1] < m_aaPos[vrt2][1])
     725              :                         return true;
     726              :         }
     727              :         return false;
     728              : }
     729              : 
     730              : template<>
     731              : inline bool SortVertexPos<3>::operator() (Vertex* vrt1, Vertex* vrt2)
     732              : {
     733              :         if(m_aaPos[vrt1][0] < m_aaPos[vrt2][0]) {
     734              :                 return true;
     735              :         }
     736              :         else if(m_aaPos[vrt1][0] == m_aaPos[vrt2][0]) {
     737              :                 if(m_aaPos[vrt1][1] < m_aaPos[vrt2][1]){
     738              :                         return true;
     739              :                 }
     740              :                 else if(m_aaPos[vrt1][1] == m_aaPos[vrt2][1]){
     741              :                         if(m_aaPos[vrt1][2] < m_aaPos[vrt2][2])
     742              :                                 return true;
     743              :                 }
     744              :                 return false;
     745              :         }
     746              :         return false;
     747              : }
     748              : 
     749              : 
     750              : /**
     751              :  * @brief Extract DoF indices for constrained and constraining indices from DoF distribution
     752              :  *
     753              :  * One cannot simply use algebra indices as constrainers and constrained vertices
     754              :  * might not have the same number of functions defined on them. Mapping correct
     755              :  * indices is only possible through DoF indices.
     756              :  *
     757              :  * @param dd                DoF distribution
     758              :  * @param hgVrt             the hanging vertex
     759              :  * @param vConstrainingVrt  vector of constraining vertices
     760              :  * @param constrainedInd    vector of DoFs indices on hanging vertex
     761              :  * @param vConstrainingInd  vector of (vector of constraining DoF indices) for constraining vertices
     762              :  * @param sortVertexPos     sorting functional for constrainers
     763              :  */
     764              : template <typename TDomain>
     765              : inline void get_algebra_indices(ConstSmartPtr<DoFDistribution> dd,
     766              :                                                  ConstrainedVertex* hgVrt,
     767              :                                                  std::vector<Vertex*>& vConstrainingVrt,
     768              :                                                  std::vector<size_t>& constrainedInd,
     769              :                                                  std::vector<std::vector<size_t> >& vConstrainingInd,
     770              :                                                  const SortVertexPos<TDomain::dim>& sortVertexPos)
     771              : {
     772              : // get subset index
     773              :         const int si = dd->subset_handler()->get_subset_index(hgVrt);
     774              : 
     775              : //      get constraining vertices
     776              :         CollectConstraining(vConstrainingVrt, *dd->multi_grid(), hgVrt);
     777              : 
     778              : #ifdef UG_PARALLEL
     779              :         std::sort(vConstrainingVrt.begin(), vConstrainingVrt.end(), sortVertexPos);
     780              : #endif
     781              : 
     782              : // clear constrainedInd
     783              :         constrainedInd.clear();
     784              : 
     785              : //      resize constraining indices
     786              :         vConstrainingInd.clear();
     787              :         vConstrainingInd.resize(vConstrainingVrt.size());
     788              : 
     789              : //      get algebra indices for constrained and constraining vertices
     790              :         if (dd->grouped())  // block algebra (assuming constrainers have exactly the same functions as constrained)
     791              :         {
     792              :         //      get indices for constrained vertex
     793              :                 dd->inner_algebra_indices(hgVrt, constrainedInd, false);
     794              : 
     795              :         //      get indices for constraining vertices
     796              :                 for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
     797              :                         dd->inner_algebra_indices(vConstrainingVrt[i], vConstrainingInd[i], false);
     798              :         }
     799              :         else  // scalar algebra
     800              :         {
     801              :                 for (size_t fct = 0; fct < dd->num_fct(); fct++)
     802              :                 {
     803              :                 //      check that function is defined on subset
     804              :                         if (!dd->is_def_in_subset(fct, si)) continue;
     805              : 
     806              :                 //      get indices for constrained vertex
     807              :                         dd->inner_algebra_indices_for_fct(hgVrt, constrainedInd, false, fct);
     808              : 
     809              :                 //      get indices for constraining vertices
     810              :                         for (size_t i = 0; i < vConstrainingVrt.size(); ++i)
     811              :                         {
     812              :                                 const int siC = dd->subset_handler()->get_subset_index(vConstrainingVrt[i]);
     813              : 
     814              :                         //      check that function is defined on subset
     815              :                                 UG_COND_THROW(!dd->is_def_in_subset(fct, siC),
     816              :                                         "Function " << fct << " is defined for a constrained vertex, "
     817              :                                         "but not for one of its constraining vertices!");
     818              : 
     819              :                                 dd->inner_algebra_indices_for_fct(vConstrainingVrt[i], vConstrainingInd[i], false, fct);
     820              :                         }
     821              :                 }
     822              :         }
     823              : }
     824              : 
     825              : 
     826              : template <typename TDomain, typename TAlgebra>
     827              : void
     828            0 : OneSideP1Constraints<TDomain,TAlgebra>::
     829              : adjust_defect(vector_type& d, const vector_type& u,
     830              :               ConstSmartPtr<DoFDistribution> dd, int type, number time,
     831              :               ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     832              :                   const std::vector<number>* vScaleMass,
     833              :               const std::vector<number>* vScaleStiff)
     834              : {
     835            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     836            0 :                 UG_THROW("index-wise assemble routine is not "
     837              :                                 "implemented for OneSideP1Constraints \n");
     838              : 
     839              : //      storage for indices and vertices
     840              :         std::vector<std::vector<size_t> > vConstrainingInd;
     841              :         std::vector<size_t>  constrainedInd;
     842              :         std::vector<Vertex*> vConstrainingVrt;
     843              : 
     844              : #ifdef UG_PARALLEL
     845              :         SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
     846              : #endif
     847              : 
     848              : //      get begin end of hanging vertices
     849              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     850            0 :         iter = dd->begin<ConstrainedVertex>();
     851            0 :         iterEnd = dd->end<ConstrainedVertex>();
     852              : 
     853              : //      loop constrained vertices
     854            0 :         for(; iter != iterEnd; ++iter)
     855              :         {
     856              :         //      get hanging vert
     857              :                 ConstrainedVertex* hgVrt = *iter;
     858              : 
     859              :         // get algebra indices for constrained and constraining vertices
     860              : #ifdef UG_PARALLEL
     861              :                 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
     862              : #else
     863            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     864              : #endif
     865              : 
     866              :         //      adapt rhs
     867            0 :                 SplitAddRhs_OneSide(d, constrainedInd, vConstrainingInd);
     868              :         }
     869            0 : }
     870              : 
     871              : 
     872              : template <typename TDomain, typename TAlgebra>
     873              : void
     874            0 : OneSideP1Constraints<TDomain,TAlgebra>::
     875              : adjust_rhs(vector_type& rhs, const vector_type& u,
     876              :            ConstSmartPtr<DoFDistribution> dd, int type, number time)
     877              : {
     878            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     879            0 :                 UG_THROW("index-wise assemble routine is not "
     880              :                                 "implemented for OneSideP1Constraints \n");
     881              : 
     882              : //      storage for indices and vertices
     883              :         std::vector<std::vector<size_t> > vConstrainingInd;
     884              :         std::vector<size_t>  constrainedInd;
     885              :         std::vector<Vertex*> vConstrainingVrt;
     886              : 
     887              : #ifdef UG_PARALLEL
     888              :         SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
     889              : #endif
     890              : 
     891              : //      get begin end of hanging vertices
     892              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     893            0 :         iter = dd->begin<ConstrainedVertex>();
     894            0 :         iterEnd = dd->end<ConstrainedVertex>();
     895              : 
     896              : //      loop constrained vertices
     897            0 :         for(; iter != iterEnd; ++iter)
     898              :         {
     899              :         //      get hanging vert
     900              :                 ConstrainedVertex* hgVrt = *iter;
     901              : 
     902              :         // get algebra indices for constrained and constraining vertices
     903              : #ifdef UG_PARALLEL
     904              :                 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
     905              : #else
     906            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     907              : #endif
     908              : 
     909              :         //      adapt rhs
     910            0 :                 SplitAddRhs_OneSide(rhs, constrainedInd, vConstrainingInd);
     911              :         }
     912            0 : }
     913              : 
     914              : template <typename TDomain, typename TAlgebra>
     915              : void
     916            0 : OneSideP1Constraints<TDomain,TAlgebra>::
     917              : adjust_jacobian(matrix_type& J, const vector_type& u,
     918              :                 ConstSmartPtr<DoFDistribution> dd, int type, number time,
     919              :                 ConstSmartPtr<VectorTimeSeries<vector_type> > vSol,
     920              :                                 const number s_a0)
     921              : {
     922            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     923            0 :                 UG_THROW("index-wise assemble routine is not "
     924              :                                 "implemented for OneSideP1Constraints \n");
     925              : 
     926              : //      storage for indices and vertices
     927              :         std::vector<std::vector<size_t> > vConstrainingInd;
     928              :         std::vector<size_t>  constrainedInd;
     929              :         std::vector<Vertex*> vConstrainingVrt;
     930              : 
     931              : #ifdef UG_PARALLEL
     932              :         SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
     933              : #endif
     934              : 
     935              : //      get begin end of hanging vertices
     936              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     937            0 :         iter = dd->begin<ConstrainedVertex>();
     938            0 :         iterEnd = dd->end<ConstrainedVertex>();
     939              : 
     940              : //      loop constrained vertices
     941            0 :         for(; iter != iterEnd; ++iter)
     942              :         {
     943              :         //      get hanging vert
     944              :                 ConstrainedVertex* hgVrt = *iter;
     945              : 
     946              :         // get algebra indices for constrained and constraining vertices
     947              : #ifdef UG_PARALLEL
     948              :                 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
     949              : #else
     950            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     951              : #endif
     952              : 
     953              :         //      Split using indices
     954            0 :                 SplitAddRow_OneSide(J, constrainedInd, vConstrainingInd);
     955              : 
     956              :         //      set interpolation
     957            0 :                 SetInterpolation(J, constrainedInd, vConstrainingInd, m_bAssembleLinearProblem);
     958              :         }
     959            0 : }
     960              : 
     961              : template <typename TDomain, typename TAlgebra>
     962              : void
     963            0 : OneSideP1Constraints<TDomain,TAlgebra>::
     964              : adjust_linear(matrix_type& mat, vector_type& rhs,
     965              :               ConstSmartPtr<DoFDistribution> dd, int type, number time)
     966              : {
     967            0 :         m_bAssembleLinearProblem = true;
     968              : 
     969            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
     970            0 :                 UG_THROW("index-wise assemble routine is not "
     971              :                                 "implemented for OneSideP1Constraints \n");
     972              : 
     973              : //      storage for indices and vertices
     974              :         std::vector<std::vector<size_t> > vConstrainingInd;
     975              :         std::vector<size_t>  constrainedInd;
     976              :         std::vector<Vertex*> vConstrainingVrt;
     977              : 
     978              : #ifdef UG_PARALLEL
     979              :         SortVertexPos<TDomain::dim> sortVertexPos(this->approximation_space()->domain());
     980              : #endif
     981              : 
     982              : //      get begin end of hanging vertices
     983              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
     984            0 :         iter = dd->begin<ConstrainedVertex>();
     985            0 :         iterEnd = dd->end<ConstrainedVertex>();
     986              : 
     987              : //      loop constraining edges
     988            0 :         for(; iter != iterEnd; ++iter)
     989              :         {
     990              :         //      get hanging vert
     991              :                 ConstrainedVertex* hgVrt = *iter;
     992              : 
     993              :         // get algebra indices for constrained and constraining vertices
     994              : #ifdef UG_PARALLEL
     995              :                 get_algebra_indices<TDomain>(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd, sortVertexPos);
     996              : #else
     997            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
     998              : #endif
     999              : 
    1000              :         //      Split using indices
    1001            0 :                 SplitAddRow_OneSide(mat, constrainedInd, vConstrainingInd);
    1002              : 
    1003              :         //      Set interpolation
    1004            0 :                 SetInterpolation(mat, constrainedInd, vConstrainingInd, true);
    1005              : 
    1006              :         //      adapt rhs
    1007            0 :                 SplitAddRhs_OneSide(rhs, constrainedInd, vConstrainingInd);
    1008              :         }
    1009            0 : }
    1010              : 
    1011              : template <typename TDomain, typename TAlgebra>
    1012              : void
    1013            0 : OneSideP1Constraints<TDomain,TAlgebra>::
    1014              : adjust_solution(vector_type& u, ConstSmartPtr<DoFDistribution> dd,
    1015              :                                 int type, number time)
    1016              : {
    1017            0 :         if(this->m_spAssTuner->single_index_assembling_enabled())
    1018            0 :                 UG_THROW("index-wise assemble routine is not "
    1019              :                                 "implemented for OneSideP1Constraints \n");
    1020              : 
    1021              : //      storage for indices and vertices
    1022              :         std::vector<std::vector<size_t> > vConstrainingInd;
    1023              :         std::vector<size_t>  constrainedInd;
    1024              :         std::vector<Vertex*> vConstrainingVrt;
    1025              : 
    1026              : //      get begin end of hanging vertices
    1027              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
    1028            0 :         iter = dd->begin<ConstrainedVertex>();
    1029            0 :         iterEnd = dd->end<ConstrainedVertex>();
    1030              : 
    1031              : //      loop constraining edges
    1032            0 :         for(; iter != iterEnd; ++iter)
    1033              :         {
    1034              :         //      get hanging vert
    1035              :                 ConstrainedVertex* hgVrt = *iter;
    1036              : 
    1037              :         // get algebra indices for constrained and constraining vertices
    1038            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
    1039              : 
    1040              :         //      Interpolate values
    1041            0 :                 InterpolateValues(u, constrainedInd, vConstrainingInd);
    1042              :         }
    1043            0 : }
    1044              : 
    1045              : 
    1046              : 
    1047              : template <typename TDomain, typename TAlgebra>
    1048              : void
    1049            0 : OneSideP1Constraints<TDomain,TAlgebra>::
    1050              : adjust_prolongation
    1051              : (
    1052              :         matrix_type& P,
    1053              :         ConstSmartPtr<DoFDistribution> ddFine,
    1054              :         ConstSmartPtr<DoFDistribution> ddCoarse,
    1055              :         int type,
    1056              :         number time
    1057              : )
    1058              : {
    1059            0 :         if (m_bAssembleLinearProblem) return;
    1060              : 
    1061            0 :         if (this->m_spAssTuner->single_index_assembling_enabled())
    1062            0 :                         UG_THROW("index-wise assemble routine is not "
    1063              :                                         "implemented for SymP1Constraints \n");
    1064              : 
    1065              : //      storage for indices and vertices
    1066              :         std::vector<std::vector<size_t> > vConstrainingInd;
    1067              :         std::vector<size_t>  constrainedInd;
    1068              :         std::vector<Vertex*> vConstrainingVrt;
    1069              : 
    1070              : //      get begin end of hanging vertices
    1071              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
    1072            0 :         iter = ddFine->begin<ConstrainedVertex>();
    1073            0 :         iterEnd = ddFine->end<ConstrainedVertex>();
    1074              : 
    1075              : //      loop constrained vertices
    1076            0 :         for(; iter != iterEnd; ++iter)
    1077              :         {
    1078              :         //      get hanging vert
    1079              :                 ConstrainedVertex* hgVrt = *iter;
    1080              : 
    1081              :         // get algebra indices for constrained and constraining vertices
    1082            0 :                 get_algebra_indices(ddFine, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
    1083              : 
    1084              :         //      set zero row
    1085              :                 size_t sz = constrainedInd.size();
    1086            0 :                 for (size_t i = 0; i < sz; ++i)
    1087            0 :                         SetRow(P, constrainedInd[i], 0.0);
    1088              :         }
    1089            0 : }
    1090              : 
    1091              : 
    1092              : template <typename TDomain, typename TAlgebra>
    1093              : void
    1094            0 : OneSideP1Constraints<TDomain,TAlgebra>::
    1095              : adjust_restriction
    1096              : (
    1097              :         matrix_type& R,
    1098              :         ConstSmartPtr<DoFDistribution> ddCoarse,
    1099              :         ConstSmartPtr<DoFDistribution> ddFine,
    1100              :         int type,
    1101              :         number time
    1102              : )
    1103            0 : {}
    1104              : 
    1105              : 
    1106              : 
    1107              : 
    1108              : template <typename TDomain, typename TAlgebra>
    1109              : void
    1110            0 : OneSideP1Constraints<TDomain,TAlgebra>::
    1111              : adjust_correction
    1112              : (       vector_type& u,
    1113              :         ConstSmartPtr<DoFDistribution> dd,
    1114              :         int type,
    1115              :         number time
    1116              : )
    1117              : {
    1118              :         //typedef typename vector_type::value_type block_type;
    1119              : 
    1120            0 :         if (this->m_spAssTuner->single_index_assembling_enabled())
    1121            0 :                 UG_THROW("index-wise assemble routine is not "
    1122              :                                 "implemented for OneSideP1Constraints \n");
    1123              : 
    1124              :         // storage for indices and vertices
    1125              :         std::vector<std::vector<size_t> > vConstrainingInd;
    1126              :         std::vector<size_t>  constrainedInd;
    1127              :         std::vector<Vertex*> vConstrainingVrt;
    1128              : 
    1129              :         // get begin end of hanging vertices
    1130              :         DoFDistribution::traits<ConstrainedVertex>::const_iterator iter, iterEnd;
    1131            0 :         iter = dd->begin<ConstrainedVertex>();
    1132            0 :         iterEnd = dd->end<ConstrainedVertex>();
    1133              : 
    1134              :         // loop constrained vertices
    1135            0 :         for (; iter != iterEnd; ++iter)
    1136              :         {
    1137              :                 // get hanging vert
    1138              :                 ConstrainedVertex* hgVrt = *iter;
    1139              : 
    1140              :                 // get algebra indices for constrained and constraining vertices
    1141            0 :                 get_algebra_indices(dd, hgVrt, vConstrainingVrt, constrainedInd, vConstrainingInd);
    1142              : 
    1143              :                 // set all entries corresponding to constrained dofs to zero
    1144            0 :                 for (size_t i = 0; i < constrainedInd.size(); ++i)
    1145            0 :                         u[constrainedInd[i]] = 0.0;
    1146              :         }
    1147            0 : }
    1148              : 
    1149              : 
    1150              : }; // namespace ug
    1151              : 
    1152              : 
    1153              : 
    1154              : #endif /* __H__UG__LIB_DISC__SPATIAL_DISC__CONSTRAINTS__CONTINUITY_CONSTRAINTS__P1_CONTINUITY_CONSTRAINTS_IMPL__ */
        

Generated by: LCOV version 2.0-1