LCOV - code coverage report
Current view: top level - ugbase/lib_algebra/active_set - active_set_impl.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 138 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 117 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Raphael Prohl
       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 ACTIVE_SET_IMPL_H_
      34              : #define ACTIVE_SET_IMPL_H_
      35              : 
      36              : #include "active_set.h"
      37              : #include "lib_disc/common/geometry_util.h"
      38              : #include "lib_disc/spatial_disc/disc_util/fe_geom.h"
      39              : 
      40              : using namespace std;
      41              : 
      42              : namespace ug {
      43              : 
      44              : template <int dim> struct face_type_traits
      45              : {
      46              :     typedef void face_type0;
      47              :         typedef void face_type1;
      48              :         typedef void DimFEGeo;
      49              : };
      50              : 
      51              : template <> struct face_type_traits<1>
      52              : {
      53              :     typedef ReferenceVertex face_type0;
      54              :         typedef ReferenceVertex face_type1;
      55              :         typedef DimFEGeometry<1, 1> DimFEGeo;
      56              : };
      57              : 
      58              : template <> struct face_type_traits<2>
      59              : {
      60              :     typedef ReferenceEdge face_type0;
      61              :         typedef ReferenceEdge face_type1;
      62              :         typedef DimFEGeometry<2, 1> DimFEGeo;
      63              : };
      64              : 
      65              : template <> struct face_type_traits<3>
      66              : {
      67              :     typedef ReferenceTriangle face_type0;
      68              :         typedef ReferenceQuadrilateral face_type1;
      69              :         typedef DimFEGeometry<3, 2> DimFEGeo;
      70              : };
      71              : 
      72              : template <typename TDomain, typename TAlgebra>
      73            0 : void ActiveSet<TDomain, TAlgebra>::prepare(function_type& u)
      74              : {
      75            0 :         m_vActiveSetGlob.resize(0); m_vActiveSetGlobOld.resize(0);
      76            0 :         m_spDD = u.dof_distribution();
      77            0 :         m_spDom = u.domain();
      78            0 : }
      79              : 
      80              : /*template <typename TDomain, typename TAlgebra>
      81              : bool ActiveSet<TDomain, TAlgebra>::check_dist_to_obs(vector_type& u)
      82              : {
      83              :         //      STILL IN PROGRESS: u sollte hier reference-position + Startl�sung sein!
      84              :         value_type dist;
      85              : 
      86              :         bool geometry_cut_by_cons = false;
      87              : 
      88              :         for(size_t i = 0; i < u.size(); i++)
      89              :         {
      90              :                 UG_LOG("u(" << i << "):" << u[i] << "\n");
      91              :                 UG_LOG("m_spObs(" << i << "):" << (*m_spObs)[i] << "\n");
      92              :                 dist = (*m_spObs)[i] - u[i];
      93              :                 UG_LOG("dist:" << dist << "\n");
      94              :                 //TODO: anstatt u muss hier die geometrische Info einflie�en!
      95              :                 for (size_t fct = 0; fct < m_nrFcts; fct++)
      96              :                 {
      97              :                         if (BlockRef(dist,fct) < 0.0) // i.e.: u < m_spObs
      98              :                         {
      99              :                                 geometry_cut_by_cons = true;
     100              :                                 break;
     101              :                         }
     102              :                 }
     103              : 
     104              :                 if (geometry_cut_by_cons)
     105              :                         break;
     106              : 
     107              :         }
     108              : 
     109              :         return geometry_cut_by_cons;
     110              : }*/
     111              : 
     112              : //      builds up a vector of global (dof,fct)-pairs, which are active (wrt. an obstacle-constraint)
     113              : template <typename TDomain, typename TAlgebra>
     114              : template <typename TElem, typename TIterator>
     115            0 : void ActiveSet<TDomain, TAlgebra>::active_index_elem(TIterator iterBegin,
     116              :                 TIterator iterEnd,
     117              :                 function_type& u,
     118              :                 function_type& rhs,
     119              :                 function_type& lagrangeMult)
     120              : {
     121              :         //      check if at least an element exists, else return
     122            0 :         if(iterBegin == iterEnd) return;
     123              : 
     124              :         int elemCounter = 0;
     125              : 
     126              :         static const int dim = function_type::dim;
     127              :         typedef typename function_type::domain_type domain_type;
     128              :         typedef typename face_type_traits<dim>::face_type0 face_type0;
     129              :         typedef typename face_type_traits<dim>::face_type1 face_type1;
     130              : 
     131              :         //      get position accessor
     132              :         typename domain_type::position_accessor_type& aaPos
     133              :                         = u.domain()->position_accessor();
     134              : 
     135              :         //      storage for corner coordinates
     136              :         vector<MathVector<dim> > vCorner;
     137              :         vector<MathVector<dim> > vSideCoPos;
     138              : 
     139              :         MathVector<dim> normal;
     140              : 
     141              :         //      local indices and local algebra
     142              :         LocalIndices ind, indObs;
     143              :         LocalVector locU, locLM, locObs;
     144              :         number complementaryVal;
     145              : 
     146              :         //      TODO: it could be more efficient to store the active elements
     147              :         //      and its active local indices as well
     148              : 
     149              :         //      Loop over all elements on active subsets
     150            0 :         for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     151              :         {
     152              :                 TElem* sideElem = *iter;
     153              : 
     154              :         //      reference object type
     155            0 :                 ReferenceObjectID roid = sideElem->reference_object_id();
     156              : 
     157              :                 const DimReferenceElement<dim-1>& rRefElem
     158              :                                 = ReferenceElementProvider::get<dim-1>(roid);
     159              : 
     160              :         //      get corners of element
     161              :                 CollectCornerCoordinates(vCorner, *sideElem, aaPos);
     162              : 
     163              :         //      here the ordering of the corners in the reference element is exploited
     164              :         //      in order to compute the outer normal later on
     165            0 :                 int nCorner = (int)vCorner.size();
     166            0 :                 for (int i = 0; i < nCorner; ++i)
     167            0 :                         vSideCoPos.push_back(vCorner[rRefElem.id(dim-1, 0, 0, i)]);
     168              : 
     169            0 :                 if (nCorner == dim)
     170              :                 {
     171            0 :                         ElementNormal<face_type0, dim>(normal, &vSideCoPos[0]);
     172              :                         UG_LOG("face_type0 \n");
     173              :                 }
     174              :                 else
     175              :                 {
     176            0 :                         ElementNormal<face_type1, dim>(normal, &vSideCoPos[0]);
     177              :                         UG_LOG("face_type1 \n");
     178              :                 }
     179              : 
     180              :                 /*for (int i = 0; i < (int)vCorner.size(); ++i)
     181              :                         UG_LOG("sideCoPos: " << sideCoPos[i] << "\n");
     182              :                 UG_LOG("normal: " << normal << "\n");*/
     183              : 
     184            0 :                 elemCounter++;
     185              : 
     186              :         //      get global indices
     187              :                 u.indices(*iter, ind); (*m_spObs).indices(*iter, indObs);
     188              : 
     189              :         //      adapt local algebra
     190            0 :                 locU.resize(ind); locLM.resize(ind); locObs.resize(indObs);
     191              : 
     192              :         //      read local values of u and lagrangeMult
     193            0 :                 GetLocalVector(locU, u); GetLocalVector(locLM, lagrangeMult);
     194            0 :                 GetLocalVector(locObs, *m_spObs);
     195              : 
     196              :         //      loop over DoFs in element and store all activeMultiIndex-pairs in vector
     197              :                 size_t nrFctElem = ind.num_fct();
     198              :                 number normOfNormal = VecLength(normal);
     199              :                 MathVector<dim> locUDof;
     200              : 
     201            0 :                 for(size_t fct = 0; fct < nrFctElem; ++fct)
     202              :                 {
     203              :                         size_t nrDoFsPerFctElem = ind.num_dof(fct);
     204            0 :                         for(size_t dof = 0; dof < nrDoFsPerFctElem; ++dof)
     205              :                         {
     206            0 :                                 for(int i = 0; i < dim; ++i)
     207            0 :                                         locUDof[i] = locU(i, dof);
     208              : 
     209              :                                 //      locLM corresponds to the lagrange multiplier lambda,
     210              :                                 //      c.f. Hintermueller/Ito/Kunisch(2003)
     211            0 :                                 number locUNormal = VecDot(locUDof, normal) / normOfNormal;
     212            0 :                                 complementaryVal = locLM(fct ,dof) + locUNormal - locObs(fct, dof);
     213              : 
     214            0 :                                 if (complementaryVal <= 1e-10){
     215            0 :                                         locLM(fct,dof) = 0.0;
     216              :                                 }
     217              :                                 else
     218              :                                 {
     219              :                                         //      create list of active global MultiIndex-pairs. Only those pairs should be attached
     220              :                                         //      which are not already a member of the 'activeSetGlob'-vector
     221              :                                         bool bAlreadyActive = false;
     222            0 :                                         for (vector<DoFIndex>::iterator itActiveInd = m_vActiveSetGlob.begin();
     223            0 :                                                         itActiveInd < m_vActiveSetGlob.end(); ++itActiveInd)
     224              :                                         {
     225            0 :                                                 if ((*itActiveInd)[0] == ind.index(fct, dof)
     226            0 :                                                                 && (*itActiveInd)[1] == ind.comp(fct, dof))
     227              :                                                         bAlreadyActive = true;
     228              :                                         }
     229              : 
     230            0 :                                         if (!bAlreadyActive)
     231              :                                         {
     232            0 :                                                 DoFIndex newActiveIndex(ind.index(fct, dof), ind.comp(fct, dof));
     233            0 :                                                 m_vActiveSetGlob.push_back(newActiveIndex);
     234              : 
     235            0 :                                                 BlockRef(rhs[ind.index(fct, dof)], ind.comp(fct, dof)) = locObs.value(fct,dof);
     236              :                                         }
     237              :                                 }
     238              :                         } // end(dof)
     239              :                 } // end(fct)
     240              : 
     241              :                 //      send local to global lagrangeMult
     242              :                 //AddLocalVector(lagrangeMult, locLM);
     243              : 
     244              :                 UG_LOG("#activeDoFFctPairs global: " << m_vActiveSetGlob.size() << "\n");
     245              :         } // end(elem)
     246            0 :         UG_LOG("#elems: " << elemCounter << "\n");
     247              : 
     248            0 : }
     249              : 
     250              : //      builds up a vector of global (dof,fct)-pairs, which are active (wrt. an obstacle-constraint)
     251              : //      and sets dirichlet values in rhs for active indices
     252              : template <typename TDomain, typename TAlgebra>
     253            0 : bool ActiveSet<TDomain, TAlgebra>::active_index(function_type& u,
     254              :                 function_type& rhs, function_type& lagrangeMult, function_type& gap)
     255              : {
     256              :         //      note: the active-index search is restricted
     257              :         //      to constraint of the form u * n <= consGF
     258            0 :         if(!m_bObs)
     259            0 :                 UG_THROW("No constraint set in ActiveSet \n");
     260              : 
     261            0 :         if (u.num_indices() != rhs.num_indices() || u.num_indices() != lagrangeMult.num_indices() )
     262            0 :                 UG_THROW("GridFunctions u, rhs and lagrangeMult need to be defined "
     263              :                                 "for the same domain and of the same size in 'ActiveSet:active_index' \n");
     264              : 
     265              :         //      remember old ActiveSet for convergence check
     266              :         //      TODO: avoid this vector copy; m_vActiveSetGlobOld really necessary?
     267            0 :         m_vActiveSetGlobOld = m_vActiveSetGlob;
     268            0 :         m_vActiveSetGlob.resize(0);
     269              : 
     270              :         //      1.) get all subsets on which the 'gap'-gridfunction is defined!
     271              :         //      -> store them in vSubsetsOflagrangeMults
     272            0 :         m_vActiveSubsets.resize(0);
     273              :         //TODO: it is only necessary to loop over all BoundarySubsets!
     274            0 :         for (int si = 0; si < m_spDD->num_subsets(); si++){
     275            0 :                 for (size_t fct = 0; fct < gap.num_fct(); fct++)
     276            0 :                         if (gap.is_def_in_subset(fct, si))
     277              :                         {
     278            0 :                                 m_vActiveSubsets.push_back(si);
     279              :                                 //      'break' is necessary to ensure that 'si' is
     280              :                                 //      only added once when several fcts of
     281              :                                 //      'gap' are defined in subset 'si'!
     282              :                                 break;
     283              :                         }
     284              :         }
     285              : 
     286            0 :         if (m_vActiveSubsets.size() == 0)
     287              :                 UG_LOG("No subsets chosen as possible active subsets. \n");
     288              : 
     289              :         UG_LOG("#sizeOfvActiveSubsets: " << m_vActiveSubsets.size() << "\n");
     290              : 
     291              :         //      2.) loop over all elements of the possible active subsets
     292            0 :         for (vector<int>::iterator activeSI = m_vActiveSubsets.begin();
     293            0 :                         activeSI != m_vActiveSubsets.end(); ++activeSI)
     294              :         {
     295              :                 //UG_LOG("activeSI: " << *activeSI << "\n");
     296            0 :                 const int subsetDim = DimensionOfSubset(*m_spDD->subset_handler(), *activeSI);
     297              :                 //UG_LOG("subsetDim: " << subsetDim << "\n");
     298              : 
     299              :                 //      3.) get localU out of u for each element and
     300              :                 //      4.) store the active global (dof,fct)-pair in m_vActiveSetGlob
     301            0 :                 switch(subsetDim)
     302              :                 {
     303              :                 case 0:
     304              :                         break;
     305            0 :                 case 1:
     306              :                         active_index_elem<RegularEdge>
     307            0 :                                 (m_spDD->template begin<RegularEdge>(*activeSI),
     308              :                                                 m_spDD->template end<RegularEdge>(*activeSI), u, rhs, lagrangeMult);
     309            0 :                         break;
     310            0 :                 case 2:
     311              :                         active_index_elem<Triangle>
     312            0 :                                 (m_spDD->template begin<Triangle>(*activeSI),
     313              :                                                 m_spDD->template end<Triangle>(*activeSI), u, rhs, lagrangeMult);
     314              :                         active_index_elem<Quadrilateral>
     315            0 :                                 (m_spDD->template begin<Quadrilateral>(*activeSI),
     316              :                                                 m_spDD->template end<Quadrilateral>(*activeSI), u, rhs, lagrangeMult);
     317            0 :                         break;
     318            0 :                 default:
     319            0 :                         UG_THROW("ActiveSet::active_index:"
     320              :                                 "SubsetDimension "<< subsetDim <<" (subset="<< *activeSI <<") not supported.");
     321              :                 }
     322              :         }
     323              : 
     324            0 :         if (m_vActiveSetGlob.size() > 0) return true;
     325            0 :         else return false;
     326              : }
     327              : 
     328              : //      sets a Dirichlet row for all active Indices
     329              : template <typename TDomain, typename TAlgebra>
     330            0 : void ActiveSet<TDomain, TAlgebra>::
     331              : set_dirichlet_rows(matrix_type& mat)
     332              : {
     333            0 :         for (vector<DoFIndex>::iterator itActiveInd = m_vActiveSetGlob.begin();
     334            0 :                         itActiveInd < m_vActiveSetGlob.end(); ++itActiveInd){
     335              :                 SetDirichletRow(mat, *itActiveInd);
     336              :         }
     337            0 : }
     338              : 
     339              : //      computes the lagrange multiplier for a given discretization
     340              : template <typename TDomain, typename TAlgebra>
     341            0 : void ActiveSet<TDomain, TAlgebra>::lagrange_multiplier(function_type& lagrangeMult,
     342              :                 const function_type& u)
     343              : {
     344              :         //      check that lagrange multiplier disc is set
     345            0 :         if (m_spLagMultDisc.invalid())
     346            0 :                 UG_THROW("No discretization set to compute the lagrange multiplier (in "
     347              :                                         "ActiveSet:lagrange_multiplier) \n");
     348              : 
     349            0 :         if(m_vActiveSetGlob.size() != 0.0)
     350              :         {
     351              :                 UG_LOG("activeDoFs in ActiveSet:lagrange_multiplier " << m_vActiveSetGlob.size() << "\n");
     352              :                 //TODO: pass localActiveElemAndIndex here!!!
     353            0 :                 m_spLagMultDisc->lagrange_multiplier(lagrangeMult, u, m_vActiveSetGlob, m_vActiveSubsets);
     354              :         }
     355            0 : }
     356              : 
     357              : template <typename TDomain, typename TAlgebra>
     358              : template <typename TElem, typename TIterator>
     359              : void ActiveSet<TDomain, TAlgebra>::lagrange_mat_inv_elem(TIterator iterBegin,
     360              :                 TIterator iterEnd, matrix_type& lagrangeMatInv)
     361              : {
     362              :         typedef typename face_type_traits<dim>::face_type0 face_type0;
     363              :         typedef typename face_type_traits<dim>::face_type1 face_type1;
     364              :         typedef typename face_type_traits<dim>::DimFEGeo sideGeo;
     365              :         typename TDomain::position_accessor_type& aaPos = m_spDom->position_accessor();
     366              : 
     367              :         //      some storage
     368              :         MathVector<dim> normal;
     369              :         vector<MathVector<dim> > vCorner;
     370              :         vector<MathVector<dim> > vSideCoPos;
     371              : 
     372              :         //      local indices and local algebra
     373              :         LocalIndices ind; LocalMatrix loclagrangeMatInv;
     374              : 
     375              :         //      Loop over all elements on active subsets
     376              :         for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     377              :         {
     378              :                 TElem* elem = *iter;
     379              : 
     380              :                 //      get global indices
     381              :                 m_spDD->indices(elem, ind);
     382              : 
     383              :                 loclagrangeMatInv.resize(ind, ind);
     384              :                 loclagrangeMatInv = 0.0;
     385              : 
     386              :                 //      reference object type and geometry
     387              :                 ReferenceObjectID sideRoid = elem->reference_object_id();
     388              :                 sideGeo geo(sideRoid, 3, LFEID(LFEID::LAGRANGE, dim, 1));
     389              : 
     390              :                 //      prepare geometry for type and order
     391              :                 try{
     392              :                         geo.update_local(sideRoid, LFEID(LFEID::LAGRANGE, dim, 1), 1);
     393              :                 }
     394              :                 UG_CATCH_THROW("ActiveSet::lagrange_mat_inv_elem:"
     395              :                                 " Cannot update local values of finite element geometry.");
     396              : 
     397              :                 //      get corners of element
     398              :                 CollectCornerCoordinates(vCorner, *elem, aaPos);
     399              : 
     400              :                 const DimReferenceElement<dim-1>& rRefElem
     401              :                                 = ReferenceElementProvider::get<dim-1>(sideRoid);
     402              : 
     403              :                 int nCorner = (int)vCorner.size();
     404              :                 for (int i = 0; i < nCorner; ++i)
     405              :                         vSideCoPos.push_back(vCorner[rRefElem.id(dim-1, 0, 0, i)]);
     406              : 
     407              :                 if (nCorner == dim)
     408              :                         ElementNormal<face_type0, dim>(normal, &vSideCoPos[0]);
     409              :                 else
     410              :                         ElementNormal<face_type1, dim>(normal, &vSideCoPos[0]);
     411              : 
     412              :                 UG_LOG("normal in lagrange_mat_inv_elem: " << normal << "\n");
     413              :                 //number normOfNormal = VecLength(normal);
     414              : 
     415              :                 try{
     416              :                         geo.update(elem, &vSideCoPos[0], LFEID(LFEID::LAGRANGE, dim, 1), 1);
     417              :                 }
     418              :                 UG_CATCH_THROW("ActiveSet::lagrange_mat_inv_elem:"
     419              :                                                 " Cannot update finite element geometry.");
     420              : 
     421              :                 for (size_t ip = 0; ip < geo.num_ip(); ++ip)
     422              :                         for(size_t sh = 0; sh < geo.num_sh(); ++sh)
     423              :                                 for (size_t i = 0; i < (size_t) dim; ++i)
     424              :                                         loclagrangeMatInv(i, sh, i, sh) += 1.0/(geo.weight(ip) * geo.shape(ip, sh));
     425              :                         // * normal[i] / normOfNormal;
     426              : 
     427              :                 AddLocalMatrixToGlobal(lagrangeMatInv, loclagrangeMatInv);
     428              :         }
     429              : }
     430              : 
     431              : template <typename TDomain, typename TAlgebra>
     432              : void ActiveSet<TDomain, TAlgebra>::lagrange_mat_inv(matrix_type& lagrangeMatInv)
     433              : {
     434              :         for (vector<int>::iterator activeSI = m_vActiveSubsets.begin();
     435              :                                 activeSI != m_vActiveSubsets.end(); ++activeSI)
     436              :         {
     437              :                 UG_LOG("activeSI: " << *activeSI << "\n");
     438              :                 const int subsetDim = DimensionOfSubset(*m_spDD->subset_handler(), *activeSI);
     439              :                 UG_LOG("subsetDim: " << subsetDim << "\n");
     440              : 
     441              :                 switch(subsetDim)
     442              :                 {
     443              :                 case 0:
     444              :                         break;
     445              :                 case 1:
     446              :                         lagrange_mat_inv_elem<RegularEdge>
     447              :                                 (m_spDD->template begin<RegularEdge>(*activeSI), m_spDD->template end<RegularEdge>(*activeSI), lagrangeMatInv);
     448              :                         break;
     449              :                 case 2:
     450              :                         lagrange_mat_inv_elem<Triangle>
     451              :                                 (m_spDD->template begin<Triangle>(*activeSI), m_spDD->template end<Triangle>(*activeSI), lagrangeMatInv);
     452              :                         lagrange_mat_inv_elem<Quadrilateral>
     453              :                                 (m_spDD->template begin<Quadrilateral>(*activeSI), m_spDD->template end<Quadrilateral>(*activeSI), lagrangeMatInv);
     454              :                         break;
     455              :                 default:
     456              :                         UG_THROW("ActiveSet::lagrange_mat_inv:"
     457              :                                 "SubsetDimension "<<subsetDim<<" (subset="<<*activeSI<<") not supported.");
     458              :                 }
     459              :         }
     460              : }
     461              : 
     462              : template <typename TDomain, typename TAlgebra>
     463            0 : void ActiveSet<TDomain, TAlgebra>::residual_lagrange_mult(vector_type& lagMult,
     464              :                 const matrix_type& mat,
     465              :                 const vector_type& u,
     466              :                 vector_type& rhs)
     467              : {
     468              :         //      only if some indices are active the lagrange multiplier is computed
     469            0 :         if(m_vActiveSetGlob.size() != 0.0)
     470              :         {
     471            0 :                 if (u.size() != lagMult.size())
     472            0 :                         UG_THROW("Temporarily u and lagMult need to be "
     473              :                                         "of same size in ActiveSet:residual_lagrange_mult \n");
     474              : 
     475              :                 /*matrix_type lagrangeMatInv;
     476              :                 //SmartPtr<AssembledLinearOperator<algebra_type> > splagrangeMatInv;
     477              :                 ass_lagrangeMatInv(lagrangeMatInv);*/
     478              : 
     479            0 :                 SmartPtr<vector_type> spMat_u = u.clone_without_values();
     480              :                 (*spMat_u).resize(u.size());
     481              : 
     482              :                 #ifdef UG_PARALLEL
     483              :                         MatMultDirect(*spMat_u, 1.0, mat, u);
     484              :                         spMat_u->set_storage_type(u.get_storage_mask());
     485              :                 #else
     486            0 :                         MatMult(*spMat_u, 1.0, mat, u);
     487              :                 #endif
     488              : 
     489              :                 //SmartPtr<vector_type> spRes = u.clone_without_values();
     490              :                 //(*spRes).resize(u.size());
     491              : 
     492              :                 //      loop MultiIndex-pairs in activeSet-vector
     493            0 :                 for (vector<DoFIndex>::iterator itActiveInd = m_vActiveSetGlob.begin();
     494            0 :                                 itActiveInd < m_vActiveSetGlob.end(); ++itActiveInd)
     495              :                 {
     496              :                         //      compute lagrange multiplier for active multiIndices
     497              :                         //      lagMult = rhs - Mat * u;
     498            0 :                         DoFRef(lagMult, *itActiveInd) = DoFRef(rhs, *itActiveInd) - DoFRef((*spMat_u), *itActiveInd);
     499              :                 }
     500              : 
     501              :                 /*#ifdef UG_PARALLEL
     502              :                         MatMultDirect(lagMult, 1.0, lagrangeMatInv, *spRes);
     503              :                 #else
     504              :                         MatMult(lagMult, 1.0, lagrangeMatInv, *spRes);
     505              :                 #endif*/
     506              : 
     507              :                 UG_LOG("new lagMult-values computed \n");
     508              :                 //UG_LOG("rhs updated \n");
     509              :         }
     510              :         else{
     511              :                 UG_LOG("no active index in residual_lagrange_mult \n");
     512              :         }
     513            0 : }
     514              : 
     515              : 
     516              : template <typename TDomain, typename TAlgebra>
     517              : template <typename TElem, typename TIterator>
     518            0 : bool ActiveSet<TDomain, TAlgebra>::check_conv_elem(TIterator iterBegin,
     519              :                 TIterator iterEnd, function_type& u, const function_type& lambda)
     520              : {
     521              :         static const int dim = function_type::dim;
     522              :         typedef typename function_type::domain_type domain_type;
     523              :         typedef typename face_type_traits<dim>::face_type0 face_type0;
     524              :         typedef typename face_type_traits<dim>::face_type1 face_type1;
     525              : 
     526              :         //      get position accessor
     527              :         typename domain_type::position_accessor_type& aaPos
     528            0 :                         = u.domain()->position_accessor();
     529              : 
     530              :         //      storage for corner coordinates
     531              :         vector<MathVector<dim> > vCorner;
     532              :         vector<MathVector<dim> > vSideCoPos;
     533              :         MathVector<dim> normal;
     534              : 
     535              :         //      local indices and local algebra
     536              :         LocalIndices ind, indObs;
     537              :         LocalVector locU, locObs, locLambda;
     538              : 
     539              :         //      Loop over all elements on active subsets
     540            0 :         for(TIterator iter = iterBegin; iter != iterEnd; ++iter)
     541              :         {
     542              :                 TElem* elem = *iter;
     543              : 
     544              :         //      reference object type
     545            0 :                 ReferenceObjectID roid = elem->reference_object_id();
     546              : 
     547              :                 const DimReferenceElement<dim-1>& rRefElem
     548              :                                 = ReferenceElementProvider::get<dim-1>(roid);
     549              : 
     550              :         //      get corners of element
     551              :                 CollectCornerCoordinates(vCorner, *elem, aaPos);
     552              : 
     553              :         //      here the ordering of the corners in the reference element is exploited
     554              :         //      in order to compute the outer normal later on
     555            0 :                 int nCorner = (int)vCorner.size();
     556            0 :                 for (int i = 0; i < nCorner; ++i)
     557            0 :                         vSideCoPos.push_back(vCorner[rRefElem.id(dim-1, 0, 0, i)]);
     558              : 
     559            0 :                 if (nCorner == dim)
     560            0 :                         ElementNormal<face_type0, dim>(normal, &vSideCoPos[0]);
     561              :                 else
     562            0 :                         ElementNormal<face_type1, dim>(normal, &vSideCoPos[0]);
     563              : 
     564              :         //      get global indices
     565              :                 u.indices(*iter, ind); (*m_spObs).indices(*iter, indObs);
     566              : 
     567              :         //      adapt local algebra
     568            0 :                 locU.resize(ind); locObs.resize(indObs); locLambda.resize(ind);
     569              : 
     570              :         //      read local values of u and lagrangeMult
     571            0 :                 GetLocalVector(locU, u); GetLocalVector(locObs, *m_spObs);
     572            0 :                 GetLocalVector(locLambda, lambda);
     573              : 
     574              :                 size_t nrFctElem = ind.num_fct();
     575              :                 number gapValue, locUNormal, kktcond;
     576              :                 number normOfNormal = VecLength(normal);
     577              :                 MathVector<dim> locUDof;
     578              : 
     579            0 :                 for(size_t fct = 0; fct < nrFctElem; ++fct)
     580              :                 {
     581              :                         size_t nrDoFsPerFctElem = ind.num_dof(fct);
     582            0 :                         for(size_t dof = 0; dof < nrDoFsPerFctElem; ++dof)
     583              :                         {
     584            0 :                                 for(int i = 0; i < dim; ++i)
     585            0 :                                         locUDof[i] = locU(i, dof);
     586            0 :                                 locUNormal = VecDot(locUDof, normal) / normOfNormal;
     587              : 
     588            0 :                                 gapValue =      locUNormal - locObs(fct, dof);
     589            0 :                                 if (gapValue > 1e-06){
     590              :                                         //      i.e.: m_spObs < u
     591              :                                         //      constraint is violated
     592            0 :                                         return false;
     593              :                                 }
     594              : 
     595            0 :                                 kktcond = gapValue * locLambda(fct, dof);
     596            0 :                                 if (kktcond > 1e-06 || kktcond < -1e-06)
     597              :                                         return false;
     598              : 
     599              :                         } // end(dof)
     600              :                 } // end(fct)
     601              :         } // end(elem)
     602              : 
     603            0 :         return true;
     604            0 : }
     605              : 
     606              : template <typename TDomain, typename TAlgebra>
     607            0 : bool ActiveSet<TDomain, TAlgebra>::check_conv(function_type& u, const function_type& lambda,
     608              :                 const size_t step)
     609              : {
     610              :         //      ensure that at least one activeSet-iteration is performed
     611            0 :         if (step <= 1)
     612              :                 return false;
     613              : 
     614              :         //      NOW TWO CHECKS WILL BE PERFORMED TO ENSURE CONVERGENCE:
     615              :         //      1.      Did some multiIndices change from 'active' to 'inactive' or vice versa
     616              :         //              in the last iteration-step?
     617              :         //      2.      Is the constraint violated for any DoFIndex?
     618              : 
     619              :         UG_LOG(m_vActiveSetGlob.size() << " indices are active at the begin "
     620              :                         "of step " << step << " ! \n");
     621              : 
     622              :         //      check if activeSet has changed
     623            0 :         if (m_vActiveSetGlob == m_vActiveSetGlobOld)
     624              :         {
     625              :                 //      check if constraint is fulfilled
     626              :                 bool bConstraintViolated = false;
     627            0 :                 for (vector<int>::iterator activeSI = m_vActiveSubsets.begin();
     628            0 :                                 activeSI != m_vActiveSubsets.end(); ++activeSI)
     629              :                 {
     630            0 :                         const int subsetDim = DimensionOfSubset(*m_spDD->subset_handler(), *activeSI);
     631            0 :                         switch(subsetDim)
     632              :                         {
     633              :                         case 0:
     634              :                                 break;
     635            0 :                         case 1:
     636            0 :                                 if (!check_conv_elem<RegularEdge>
     637            0 :                                         (m_spDD->template begin<RegularEdge>(*activeSI), m_spDD->template end<RegularEdge>(*activeSI),
     638              :                                                         u, lambda))
     639              :                                 {bConstraintViolated = true;}
     640              : 
     641              :                                 break;
     642            0 :                         case 2:
     643            0 :                                 if (!check_conv_elem<Triangle>
     644            0 :                                         (m_spDD->template begin<Triangle>(*activeSI),
     645              :                                                         m_spDD->template end<Triangle>(*activeSI), u, lambda))
     646              :                                 {bConstraintViolated = true;}
     647              : 
     648            0 :                                 if (!check_conv_elem<Quadrilateral>
     649            0 :                                         (m_spDD->template begin<Quadrilateral>(*activeSI),
     650              :                                                         m_spDD->template end<Quadrilateral>(*activeSI), u, lambda))
     651              :                                 {bConstraintViolated = true;}
     652              : 
     653              :                                 break;
     654            0 :                         default:
     655            0 :                                 UG_THROW("ActiveSet::check_conv:"
     656              :                                         "SubsetDimension "<< subsetDim <<" (subset="<< *activeSI <<") not supported.");
     657              :                         }
     658              : 
     659            0 :                         if (bConstraintViolated)
     660              :                                 return false;
     661              :                 }
     662              : 
     663              :                 //      activeSet remains unchanged & constraint is fulfilled for all indices
     664              :                 return true;
     665              :         }
     666              :         else{
     667              :                 return false;
     668              :         }
     669              : }
     670              : 
     671              : 
     672              : template <typename TDomain, typename TAlgebra>
     673            0 : bool ActiveSet<TDomain, TAlgebra>::check_inequ(const matrix_type& mat,
     674              :                                 const vector_type& u,
     675              :                                 const vector_type& lambda,
     676              :                                 const vector_type& rhs)
     677              : {
     678            0 :         if (u.size() != lambda.size())
     679            0 :                 UG_THROW("Temporarily u and lambda need to be "
     680              :                                 "of same size in ActiveSet:check_inequ \n");
     681              : 
     682            0 :         SmartPtr<vector_type> spMat_u = u.clone_without_values();
     683            0 :         SmartPtr<vector_type> spRes = u.clone_without_values();
     684              :         (*spMat_u).resize(u.size()); (*spRes).resize(u.size());
     685              : 
     686              :         #ifdef UG_PARALLEL
     687              :                 MatMultDirect(*spMat_u, 1.0, mat, u);
     688              :                 spMat_u->set_storage_type(u.get_storage_mask());
     689              :                 spRes->set_storage_type(u.get_storage_mask());
     690              :         #else
     691            0 :                 MatMult(*spMat_u, 1.0, mat, u);
     692              :         #endif
     693              : 
     694            0 :         for (size_t i = 0; i < u.size(); ++i)
     695              :         {
     696              :                 //if (lambda[i] < -1e-06)
     697              :                 //      return false;
     698              : 
     699            0 :                 (*spRes)[i] = (*spMat_u)[i] - rhs[i]; //+ lambda[i] - rhs[i]; //
     700            0 :                 UG_LOG("lambda["<< i << "]: " << lambda[i] <<", res[" << i << "]: " << (*spRes)[i] << "\n");
     701              :                 //if ((*spRes)[i] > 1e-06)
     702              :                 //      return false;
     703              :         }
     704              : 
     705            0 :         return true;
     706              : }
     707              : 
     708              : }; // namespace ug
     709              : 
     710              : #endif /* ACTIVE_SET_IMPL_H_ */
        

Generated by: LCOV version 2.0-1