LCOV - code coverage report
Current view: top level - ugbase/lib_disc/function_spaces - adaption_surface_grid_function.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 134 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 132 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "adaption_surface_grid_function.h"
      34              : #include "lib_disc/dof_manager/orientation.h"
      35              : #include "lib_disc/function_spaces/local_transfer_interface.h"
      36              : 
      37              : namespace ug{
      38              : 
      39              : template <typename TDomain>
      40            0 : AdaptionSurfaceGridFunction<TDomain>::
      41              : AdaptionSurfaceGridFunction(SmartPtr<TDomain> spDomain, bool bObserveStorage)
      42              :         :       m_spDomain(spDomain),
      43              :                 m_spGrid(spDomain->grid()),
      44            0 :                 m_bObserveStorage(bObserveStorage),
      45            0 :                 m_aValue(true)
      46            0 : {}
      47              : 
      48              : template <typename TDomain>
      49            0 : void AdaptionSurfaceGridFunction<TDomain>::
      50              : prolongate(const GridMessage_Adaption& msg)
      51              : {
      52              : //      \todo: this temporary - handle more flexible
      53              :         m_vpProlong.clear();
      54            0 :         for(size_t fct = 0; fct < m_spDDInfo->num_fct(); ++fct)
      55            0 :                 m_vpProlong.push_back(GetStandardElementProlongation<TDomain>(m_spDDInfo->lfeid(fct)));
      56              : 
      57              :         const GridObjectCollection& goc = msg.affected_elements();
      58            0 :         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
      59              :         {
      60            0 :                 prolongate<Vertex>(msg, lvl);
      61            0 :                 prolongate<Edge>(msg, lvl);
      62            0 :                 prolongate<Face>(msg, lvl);
      63            0 :                 prolongate<Volume>(msg, lvl);
      64              :         }
      65            0 : }
      66              : 
      67              : template <typename TDomain>
      68              : template <typename TBaseElem>
      69            0 : void AdaptionSurfaceGridFunction<TDomain>::
      70              : prolongate(const GridMessage_Adaption& msg, const size_t lvl)
      71              : {
      72              :         const GridBaseObjectId gbo = (GridBaseObjectId)TBaseElem::BASE_OBJECT_ID;
      73              : 
      74              : //      extract and init prolongations working on the base element type
      75              :         std::vector<SmartPtr<IElemProlongation<TDomain> > > vpProlong;
      76            0 :         for(size_t fct = 0; fct < m_vpProlong.size(); ++fct){
      77              : 
      78            0 :                 if(!m_vpProlong[fct]->perform_prolongation_on(gbo)) continue;
      79              : 
      80            0 :                 m_vpProlong[fct]->init(m_spDomain,
      81            0 :                                        make_sp(new ValueAccessor(*this, fct)),
      82            0 :                                        make_sp(new ValueAccessor(*this, fct)));
      83              : 
      84            0 :                 vpProlong.push_back(m_vpProlong[fct]);
      85              :         }
      86              : 
      87              : //      check that something to do
      88            0 :         if(vpProlong.empty()) return;
      89              : 
      90              : //      iterators
      91              :         const GridObjectCollection& goc = msg.affected_elements();
      92              :         typedef typename GridObjectCollection::traits<TBaseElem>::const_iterator const_iterator;
      93              : 
      94              : 
      95              :         const_iterator iter = goc.begin<TBaseElem>(lvl);
      96              :         const_iterator iterEnd = goc.end<TBaseElem>(lvl);
      97              : 
      98              : //      loop base element type
      99            0 :         for( ; iter != iterEnd; ++iter)
     100              :         {
     101              :         //      get parent element, that has been refined
     102              :                 TBaseElem* parent = *iter;
     103              : 
     104              :         //      call implementations
     105            0 :                 for(size_t f = 0; f < vpProlong.size(); ++f){
     106            0 :                         vpProlong[f]->prolongate(parent);
     107              :                 }
     108              :         }
     109            0 : }
     110              : 
     111              : //template <typename TElem, typename TSubElem>
     112              : //static void select_associated(MGSelector& sel, TElem* elem)
     113              : //{
     114              : //      MultiGrid* mg = sel.multi_grid();
     115              : //
     116              : //      typename Grid::traits<TSubElem>::secure_container vSubElem;
     117              : //      mg->associated_elements(vSubElem, elem);
     118              : //      for(size_t i = 0; i < vSubElem.size(); ++i)
     119              : //              sel.select(vSubElem[i]);
     120              : //}
     121              : //
     122              : //template <typename TElem>
     123              : //static void select_associated(MGSelector& sel, TElem* elem)
     124              : //{
     125              : //      // add all subelements
     126              : //      switch(TElem::dim){
     127              : //              case 3: select_associated<TElem, Face>(sel, elem);
     128              : //              case 2: select_associated<TElem, Edge>(sel, elem);
     129              : //              case 1: select_associated<TElem, Vertex>(sel, elem);
     130              : //              default: ;
     131              : //      }
     132              : //}
     133              : //
     134              : //static void select_associated(MGSelector& sel, GridObject* elem)
     135              : //{
     136              : //      switch(elem->base_object_id()){
     137              : //              case VERTEX: return; // no sub elems
     138              : //              case EDGE: select_associated(sel, static_cast<Edge*>(elem)); return;
     139              : //              case FACE: select_associated(sel, static_cast<Face*>(elem)); return;
     140              : //              case VOLUME: select_associated(sel, static_cast<Volume*>(elem)); return;
     141              : //              default: UG_THROW("Dim not supported.");
     142              : //      }
     143              : //}
     144              : 
     145              : 
     146              : template <typename TDomain>
     147              : template <typename TBaseElem>
     148            0 : void AdaptionSurfaceGridFunction<TDomain>::
     149              : select_parents(MGSelector& sel, const GridMessage_Adaption& msg)
     150              : {
     151              : //      iterators
     152              :         const GridObjectCollection& goc = msg.affected_elements();
     153              :         typedef typename GridObjectCollection::traits<TBaseElem>::const_iterator const_iterator;
     154              : 
     155            0 :         for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
     156              :         {
     157              :                 const_iterator iter = goc.begin<TBaseElem>(lvl);
     158              :                 const_iterator iterEnd = goc.end<TBaseElem>(lvl);
     159              : 
     160              :         //      loop base element type
     161            0 :                 for( ; iter != iterEnd; ++iter)
     162              :                 {
     163              :                 //      get parent element, that is marked for coarsening
     164              :                         TBaseElem* elem = *iter;
     165              : 
     166              :                         // exclude if not in surface or no shadow
     167            0 :                         if(m_aaValue[elem].size() != m_spDDInfo->num_fct())
     168            0 :                                 continue;
     169              : 
     170              :                 //      get parent
     171              :                         GridObject* parent = sel.multi_grid()->get_parent(elem);
     172              : 
     173              :                 //      check whether a parent exist and if it is of the same type as the
     174              :                 //      elements considered. Parents of a different type are handled in
     175              :                 //      other calls to this method
     176            0 :                         if(!parent || (parent->base_object_id() != TBaseElem::BASE_OBJECT_ID))
     177            0 :                                 continue;
     178              : 
     179              :                 //      select parent
     180            0 :                         sel.select(parent);
     181              :                 }
     182              :         }
     183            0 : }
     184              : 
     185              : template <typename TDomain>
     186            0 : void AdaptionSurfaceGridFunction<TDomain>::
     187              : do_restrict(const GridMessage_Adaption& msg)
     188              : {
     189              : //      \todo: this temporary - handle more flexible
     190              :         m_vpRestrict.clear();
     191            0 :         for(size_t fct = 0; fct < m_spDDInfo->num_fct(); ++fct)
     192            0 :                 m_vpRestrict.push_back(GetStandardElementRestriction<TDomain>(m_spDDInfo->lfeid(fct)));
     193              : 
     194            0 :         MGSelector sel(*m_spGrid);
     195              : 
     196            0 :         if(m_aaValue.is_valid_vertex_accessor())
     197            0 :                 select_parents<Vertex>(sel, msg);
     198            0 :         if(m_aaValue.is_valid_edge_accessor())
     199            0 :                 select_parents<Edge>(sel, msg);
     200            0 :         if(m_aaValue.is_valid_face_accessor())
     201            0 :                 select_parents<Face>(sel, msg);
     202            0 :         if(m_aaValue.is_valid_volume_accessor())
     203            0 :                 select_parents<Volume>(sel, msg);
     204              : 
     205            0 :         do_restrict<Vertex>(sel, msg);
     206            0 :         do_restrict<Edge>(sel, msg);
     207            0 :         do_restrict<Face>(sel, msg);
     208            0 :         do_restrict<Volume>(sel, msg);
     209            0 : }
     210              : 
     211              : template <typename TDomain>
     212              : template <typename TBaseElem>
     213            0 : void AdaptionSurfaceGridFunction<TDomain>::
     214              : do_restrict(const MGSelector& sel, const GridMessage_Adaption& msg)
     215              : {
     216              :         const GridBaseObjectId gbo = (GridBaseObjectId)TBaseElem::BASE_OBJECT_ID;
     217              : 
     218              : //      extract and init prolongations working on the base element type
     219              :         std::vector<SmartPtr<IElemRestriction<TDomain> > > vpRestrict;
     220            0 :         for(size_t fct = 0; fct < m_vpRestrict.size(); ++fct){
     221              : 
     222            0 :                 if(!m_vpRestrict[fct]->perform_restriction_on(gbo)) continue;
     223              : 
     224            0 :                 m_vpRestrict[fct]->init(m_spDomain,
     225            0 :                                         make_sp(new ValueAccessor(*this, fct)),
     226            0 :                                         make_sp(new ValueAccessor(*this, fct)));
     227              : 
     228            0 :                 vpRestrict.push_back(m_vpRestrict[fct]);
     229              :         }
     230              : 
     231              : //      check that something to do
     232            0 :         if(vpRestrict.empty()) return;
     233              : 
     234              : //      check that correct attachments used
     235            0 :         if(m_spDDInfo->max_dofs(gbo) == 0) return;
     236              : 
     237              : //      iterators
     238              :         typedef typename Selector::traits<TBaseElem>::const_level_iterator const_iterator;
     239              : 
     240            0 :         for(int lvl = sel.num_levels() - 1; lvl >= 0; --lvl)
     241              :         {
     242              :                 const_iterator iter = sel.begin<TBaseElem>(lvl);
     243              :                 const_iterator iterEnd = sel.end<TBaseElem>(lvl);
     244              : 
     245              :         //      loop base element type
     246            0 :                 for( ; iter != iterEnd; ++iter)
     247              :                 {
     248              :                 //      get parent element, that has been refined
     249              :                         TBaseElem* parent = *iter;
     250              : 
     251              :                 //      add storage for parent
     252            0 :                         obj_created(parent);
     253              : 
     254              :                 //      call implementations
     255            0 :                         for(size_t f = 0; f < vpRestrict.size(); ++f){
     256            0 :                                 vpRestrict[f]->do_restrict(parent);
     257              :                         }
     258              :                 }
     259              :         }
     260            0 : }
     261              : 
     262              : 
     263              : template <typename TDomain>
     264            0 : void AdaptionSurfaceGridFunction<TDomain>::
     265              : attach_entries(ConstSmartPtr<DoFDistributionInfo> spDDInfo)
     266              : {
     267              :         GFUNCADAPT_PROFILE_FUNC();
     268            0 :         if(m_spGrid.invalid()) UG_THROW("Grid missing")
     269              : 
     270            0 :         m_spDDInfo = spDDInfo;
     271              : 
     272              : //      get required elem types
     273            0 :         const bool vrt = (spDDInfo->max_dofs(VERTEX) > 0);
     274            0 :         const bool edge = (spDDInfo->max_dofs(EDGE) > 0);
     275            0 :         const bool face = (spDDInfo->max_dofs(FACE) > 0);
     276            0 :         const bool vol = (spDDInfo->max_dofs(VOLUME) > 0);
     277              : 
     278              : //      attach storage arrays
     279            0 :         if(vrt) m_spGrid->attach_to<Vertex>(m_aValue);
     280            0 :         if(edge) m_spGrid->attach_to<Edge>(m_aValue);
     281            0 :         if(face) m_spGrid->attach_to<Face>(m_aValue);
     282            0 :         if(vol) m_spGrid->attach_to<Volume>(m_aValue);
     283              : 
     284              : //      prepare access
     285            0 :         m_aaValue.access(*m_spGrid, m_aValue, vrt, edge, face, vol);
     286              : 
     287            0 :         if(m_bObserveStorage)
     288              :         {
     289              :         //      get type of observer
     290              :                 int type = OT_GRID_OBSERVER;
     291            0 :                 if(vrt) type |= OT_VERTEX_OBSERVER;
     292            0 :                 if(edge) type |= OT_EDGE_OBSERVER;
     293            0 :                 if(face) type |= OT_FACE_OBSERVER;
     294            0 :                 if(vol) type |= OT_VOLUME_OBSERVER;
     295              : 
     296              :         //      register observer
     297            0 :                 m_spGrid->register_observer(this, type);
     298              :         }
     299            0 : }
     300              : 
     301              : template <typename TDomain>
     302              : template <typename TElem>
     303            0 : void AdaptionSurfaceGridFunction<TDomain>::detach_entries()
     304              : {
     305            0 :         if(m_spGrid.invalid()) UG_THROW("Grid missing")
     306              : 
     307            0 :         if(m_spGrid->has_attachment<TElem>(m_aValue))
     308            0 :                 m_spGrid->detach_from<TElem>(m_aValue);
     309            0 : }
     310              : 
     311              : template <typename TDomain>
     312            0 : void AdaptionSurfaceGridFunction<TDomain>::detach_entries()
     313              : {
     314              :         GFUNCADAPT_PROFILE_FUNC();
     315              : //      remove attachments
     316            0 :         if(m_aaValue.is_valid_vertex_accessor()) detach_entries<Vertex>();
     317            0 :         if(m_aaValue.is_valid_edge_accessor()) detach_entries<Edge>();
     318            0 :         if(m_aaValue.is_valid_face_accessor()) detach_entries<Face>();
     319            0 :         if(m_aaValue.is_valid_volume_accessor()) detach_entries<Volume>();
     320            0 :         m_aaValue = MultiElementAttachmentAccessor<AValues>();
     321              : 
     322              : //      stop observing grid
     323            0 :         if(m_bObserveStorage)
     324            0 :                 m_spGrid->unregister_observer(this);
     325            0 : }
     326              : 
     327              : ////////////////////////////////////////////////////////////////////////////////
     328              : // Value accessor
     329              : ////////////////////////////////////////////////////////////////////////////////
     330              : 
     331              : template <typename TDomain>
     332            0 : AdaptionSurfaceGridFunction<TDomain>::ValueAccessor::
     333              : ValueAccessor(AdaptionSurfaceGridFunction<TDomain>& rASGF,
     334              :                           size_t fct)
     335            0 :         : m_rASGF(rASGF), m_fct(fct)
     336              : {
     337            0 :         for(int g = 0; g < NUM_GEOMETRIC_BASE_OBJECTS; ++g)
     338              :         {
     339              :                 const GridBaseObjectId gbo = (GridBaseObjectId)g;
     340            0 :                 m_HasDoFs[gbo] = (m_rASGF.m_spDDInfo->max_fct_dofs(fct, gbo) > 0);
     341              :         }
     342            0 : }
     343              : 
     344              : template <typename TDomain>
     345              : void
     346            0 : AdaptionSurfaceGridFunction<TDomain>::ValueAccessor::
     347              : access_inner(GridObject* elem)
     348              : {
     349              :         UG_ASSERT(m_fct < m_rASGF.m_aaValue[elem].size(), "Only storage for "
     350              :                   <<m_rASGF.m_aaValue[elem].size()<<" fcts, but fct-cmp "
     351              :                   <<m_fct<<" requested on "<< ElementDebugInfo(*m_rASGF.m_spDomain->grid(), elem))
     352            0 :         std::vector<number>& vVal = m_rASGF.m_aaValue[elem][m_fct];
     353            0 :         m_Val.resize(vVal.size());
     354            0 :         for(size_t i = 0; i < vVal.size(); ++i)
     355            0 :                 m_Val[i] = &vVal[i];
     356            0 : }
     357              : 
     358              : template <typename TDomain>
     359              : template <typename TBaseElem, typename TSubBaseElem>
     360              : void
     361            0 : AdaptionSurfaceGridFunction<TDomain>::ValueAccessor::
     362              : access_closure(TBaseElem* elem)
     363              : {
     364              : 
     365              :         typename Grid::traits<TSubBaseElem>::secure_container vSubElem;
     366            0 :         m_rASGF.m_spGrid->associated_elements_sorted(vSubElem, elem);
     367              : 
     368              :         std::vector<size_t> vOrientOffset;
     369              : 
     370            0 :         for(size_t i = 0; i < vSubElem.size(); ++i)
     371              :         {
     372              :         //      get subelement
     373              :                 TSubBaseElem* subElem = vSubElem[i];
     374              :                 UG_ASSERT(m_fct < m_rASGF.m_aaValue[subElem].size(), "Only storage for "
     375              :                           <<m_rASGF.m_aaValue[subElem].size()<<" fcts, but fct-cmp "
     376              :                           <<m_fct<<" requested on "<<ElementDebugInfo(*m_rASGF.m_spDomain->grid(), subElem))
     377            0 :                 std::vector<number>& vVal = m_rASGF.m_aaValue[subElem][m_fct];
     378              : 
     379              :         //      get the orientation for this subelement
     380            0 :                 ComputeOrientationOffset(vOrientOffset, elem, subElem, i,
     381              :                                                                  m_rASGF.m_spDDInfo->lfeid(m_fct));
     382              : 
     383              :                 UG_ASSERT(vOrientOffset.size() == vVal.size() ||
     384              :                                   vOrientOffset.empty(), "Orientation wrong");
     385              : 
     386              :         //      cache access
     387            0 :                 if(vOrientOffset.empty()){
     388            0 :                         for(size_t j = 0; j < vVal.size(); ++j)
     389            0 :                                 m_Val.push_back(&vVal[ j ]);
     390              :                 }else{
     391            0 :                         for(size_t j = 0; j < vVal.size(); ++j)
     392            0 :                                 m_Val.push_back(&vVal[ vOrientOffset[j] ]);
     393              :                 }
     394              :         }
     395            0 : }
     396              : 
     397              : template <typename TDomain>
     398              : template <typename TBaseElem>
     399              : void
     400            0 : AdaptionSurfaceGridFunction<TDomain>::ValueAccessor::
     401              : access_closure(TBaseElem* elem)
     402              : {
     403              :         m_Val.clear();
     404            0 :         if(m_HasDoFs[VERTEX]) access_closure<TBaseElem, Vertex>(elem);
     405            0 :         if(m_HasDoFs[EDGE]) access_closure<TBaseElem, Edge>(elem);
     406            0 :         if(m_HasDoFs[FACE]) access_closure<TBaseElem, Face>(elem);
     407            0 :         if(m_HasDoFs[VOLUME]) access_closure<TBaseElem, Volume>(elem);
     408            0 : }
     409              : 
     410              : template <typename TDomain>
     411              : void
     412            0 : AdaptionSurfaceGridFunction<TDomain>::ValueAccessor::
     413              : access_closure(GridObject* elem)
     414              : {
     415            0 :         switch(elem->base_object_id()){
     416            0 :                 case VERTEX: access_closure(static_cast<Vertex*>(elem)); return;
     417            0 :                 case EDGE: access_closure(static_cast<Edge*>(elem)); return;
     418            0 :                 case FACE: access_closure(static_cast<Face*>(elem)); return;
     419            0 :                 case VOLUME: access_closure(static_cast<Volume*>(elem)); return;
     420            0 :                 default: UG_THROW("Base object id not found.")
     421              :         }
     422              : }
     423              : 
     424              : 
     425              : #ifdef UG_DIM_1
     426              : template class AdaptionSurfaceGridFunction<Domain1d>;
     427              : #endif
     428              : #ifdef UG_DIM_2
     429              : template class AdaptionSurfaceGridFunction<Domain2d>;
     430              : #endif
     431              : #ifdef UG_DIM_3
     432              : template class AdaptionSurfaceGridFunction<Domain3d>;
     433              : #endif
     434              : 
     435              : } // end namespace ug
        

Generated by: LCOV version 2.0-1