LCOV - code coverage report
Current view: top level - ugbase/lib_grid/attachments - attachment_pipe.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 76.8 % 82 63
Test Date: 2025-09-21 23:31:46 Functions: 13.2 % 281 37

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       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 __UTIL__ATTACHMENT_PIPE__IMPL__
      34              : #define __UTIL__ATTACHMENT_PIPE__IMPL__
      35              : 
      36              : #include "attachment_pipe.h"
      37              : #include "common/profiler/profiler.h"
      38              : 
      39              : namespace ug
      40              : {
      41              : template <class TElem, class TElemHandler>
      42              : AttachmentPipe<TElem, TElemHandler>::
      43              : AttachmentPipe() :
      44              :         m_attachmentEntryIteratorHash(13),
      45              :         m_numElements(0),
      46              :         m_numDataEntries(0),
      47              :         m_containerSize(0),
      48              :         m_pHandler(NULL)
      49              : {
      50              : }
      51              : 
      52              : template <class TElem, class TElemHandler>
      53            4 : AttachmentPipe<TElem, TElemHandler>::
      54              : AttachmentPipe(typename atraits::ElemHandlerPtr pHandler) :
      55            4 :         m_attachmentEntryIteratorHash(13),
      56            4 :         m_numElements(0),
      57            4 :         m_numDataEntries(0),
      58            4 :         m_containerSize(0),
      59            4 :         m_pHandler(pHandler)
      60              : {
      61            4 : }
      62              : 
      63              : template <class TElem, class TElemHandler>
      64            4 : AttachmentPipe<TElem, TElemHandler>::
      65              : ~AttachmentPipe()
      66              : {
      67              : //      clear attachment entries
      68            4 :         for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
      69            8 :                                         iter != m_attachmentEntryContainer.end(); iter++)
      70              :         {
      71            4 :                 delete (*iter).m_pAttachment;
      72            4 :                 delete (*iter).m_pContainer;
      73              :         }
      74            4 : }
      75              : 
      76              : template <class TElem, class TElemHandler>
      77              : void
      78              : AttachmentPipe<TElem, TElemHandler>::
      79              : clear()
      80              : {
      81              :         clear_elements();
      82              :         clear_attachments();
      83              : }
      84              : 
      85              : template <class TElem, class TElemHandler>
      86              : void
      87              : AttachmentPipe<TElem, TElemHandler>::
      88              : clear_elements()
      89              : {
      90              :         m_stackFreeEntries = UINTStack();
      91              :         resize_attachment_containers(0);
      92              :         m_numElements = 0;
      93              :         m_numDataEntries = 0;
      94              : }
      95              : 
      96              : template <class TElem, class TElemHandler>
      97              : void
      98              : AttachmentPipe<TElem, TElemHandler>::
      99              : clear_attachments()
     100              : {
     101              :         m_attachmentEntryContainer.clear();
     102              :         m_attachmentEntryIteratorHash.clear();
     103              : }
     104              : 
     105              : template <class TElem, class TElemHandler>
     106              : void
     107              : AttachmentPipe<TElem, TElemHandler>::
     108              : reset_values(size_t dataIndex)
     109              : {
     110            0 :         for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     111            0 :                                         iter != m_attachmentEntryContainer.end(); iter++)
     112              :         {
     113            0 :                 (*iter).m_pContainer->reset_entry(dataIndex);
     114              :         }
     115              : }
     116              : 
     117              : 
     118              : 
     119              : template <class TElem, class TElemHandler>
     120              : void
     121              : AttachmentPipe<TElem, TElemHandler>::
     122              : reserve(size_t numElems)
     123              : {
     124            0 :         if(numElems > get_container_size())
     125              :                 resize_attachment_containers(numElems);
     126              : }
     127              : 
     128              : template <class TElem, class TElemHandler>
     129              : void
     130            7 : AttachmentPipe<TElem, TElemHandler>::
     131              : register_element(TElem elem)
     132              : {
     133              :         size_t newInd;
     134              : //      check if there is a free entry
     135              : 
     136            7 :         if(!m_stackFreeEntries.empty())
     137              :         {
     138              :         //      take it
     139            0 :                 newInd = m_stackFreeEntries.top();
     140              :                 m_stackFreeEntries.pop();
     141              : 
     142              :         //      initialize attachments with default constructor
     143              :                 reset_values(newInd);
     144              :         }
     145              :         else
     146              :         {
     147              :         //      add a new entry
     148            7 :                 newInd = m_numDataEntries++;
     149              :         //      make sure that the data containers are big enough.
     150              :                 grow_attachment_containers(m_numDataEntries);
     151              :         }
     152              : 
     153              : //      assign new attachment index to the element
     154            7 :         atraits::set_data_index(m_pHandler, elem, newInd);
     155              : 
     156              : //      increase element count
     157            7 :         m_numElements++;
     158            7 : }
     159              : 
     160              : template <class TElem, class TElemHandler>
     161              : void
     162            7 : AttachmentPipe<TElem, TElemHandler>::
     163              : unregister_element(const TElem& elem)
     164              : {
     165              : //      get the attachment index
     166            7 :         size_t ind = atraits::get_data_index(m_pHandler, elem);
     167              : //      store the index in the stack of free entries
     168              :         m_stackFreeEntries.push(ind);
     169              : //      decrease element count
     170            7 :         m_numElements--;
     171            7 : }
     172              : 
     173              : 
     174              : template <class TElem, class TElemHandler>
     175              : template <class TAttachment>
     176              : void
     177            0 : AttachmentPipe<TElem, TElemHandler>::
     178              : attach(TAttachment& attachment,
     179              :                 const typename TAttachment::ValueType& defaultValue,
     180              :                 uint options)
     181              : {
     182              : //      make sure, that the attachment is not already attached
     183            0 :         if(!has_attachment(attachment))
     184              :         {
     185              :         //      create a new element and insert it into the entryContainer.
     186              :         //      resize the new data-container to the size of the element container.
     187              :         //      store the returned iterator in the iteratorHash to allow fast access.
     188            0 :                 IAttachment* pClonedAttachment = attachment.clone();
     189            0 :                 IAttachmentDataContainer* pClonedContainer = attachment.create_container(defaultValue);
     190            0 :                 pClonedContainer->resize(get_container_size());
     191              :                 AttachmentEntryIterator iter = m_attachmentEntryContainer.
     192            0 :                                 insert(m_attachmentEntryContainer.end(),
     193            0 :                                                 AttachmentEntry(pClonedAttachment,
     194              :                                                 pClonedContainer, options));
     195            0 :                 m_attachmentEntryIteratorHash.insert(pClonedAttachment->id(), iter);
     196              :         }
     197              :         else
     198              :         {
     199              : //TODO: do something!
     200              :         }
     201            0 : }
     202              : 
     203              : template <class TElem, class TElemHandler>
     204              : void
     205           11 : AttachmentPipe<TElem, TElemHandler>::
     206              : attach(IAttachment& attachment, uint options)
     207              : {
     208              : //      make sure, that the attachment is not already attached
     209           11 :         if(!has_attachment(attachment))
     210              :         {
     211              :         //      create a new element and insert it into the entryContainer.
     212              :         //      resize the new data-container to the size of the element container.
     213              :         //      store the returned iterator in the iteratorHash to allow fast access.
     214           11 :                 IAttachment* pClonedAttachment = attachment.clone();
     215           11 :                 IAttachmentDataContainer* pClonedContainer = pClonedAttachment->create_container();
     216           11 :                 pClonedContainer->resize(get_container_size());
     217           11 :                 AttachmentEntryIterator iter = m_attachmentEntryContainer.insert(m_attachmentEntryContainer.end(), AttachmentEntry(pClonedAttachment, pClonedContainer, options));
     218           11 :                 m_attachmentEntryIteratorHash.insert(pClonedAttachment->id(), iter);
     219              :         }
     220              :         else
     221              :         {
     222              : //TODO: do something!
     223              :         }
     224           11 : }
     225              : 
     226              : template <class TElem, class TElemHandler>
     227              : void
     228            7 : AttachmentPipe<TElem, TElemHandler>::
     229              : detach(IAttachment& attachment)
     230              : {
     231            7 :         if(has_attachment(attachment))
     232              :         {
     233            7 :                 AttachmentEntryIterator iter = m_attachmentEntryIteratorHash.get_entry(attachment.id());
     234            7 :                 delete ((*iter).m_pAttachment);
     235            7 :                 ((*iter).m_pAttachment) = NULL;
     236            7 :                 delete((*iter).m_pContainer);
     237            7 :                 ((*iter).m_pContainer) = NULL;
     238            7 :                 m_attachmentEntryContainer.erase(iter);
     239            7 :                 m_attachmentEntryIteratorHash.erase(attachment.id());
     240              :         }
     241            7 : }
     242              : 
     243              : template <class TElem, class TElemHandler>
     244              : bool
     245              : AttachmentPipe<TElem, TElemHandler>::
     246              : has_attachment(IAttachment& attachment) const
     247              : {
     248              :         return m_attachmentEntryIteratorHash.has_entry(attachment.id());
     249              : }
     250              : 
     251              : 
     252              : template <class TElem, class TElemHandler>
     253              : template <class TAttachment>
     254              : typename TAttachment::ValueType*
     255              : AttachmentPipe<TElem, TElemHandler>::
     256              : get_data_array(TAttachment& attachment)
     257              : {
     258              :         if(has_attachment(attachment))
     259              :                 return get_data_container(attachment)->get_ptr();
     260              : 
     261              :         return NULL;
     262              : }
     263              : 
     264              : template <class TElem, class TElemHandler>
     265              : IAttachmentDataContainer*
     266            0 : AttachmentPipe<TElem, TElemHandler>::
     267              : get_data_container(IAttachment& attachment) const
     268              : {
     269              :         AttachmentEntryIterator iter;
     270            0 :         if(m_attachmentEntryIteratorHash.get_entry(iter, attachment.id()))
     271            0 :                 return iter->m_pContainer;
     272              :         return NULL;
     273              : }
     274              : 
     275              : template <class TElem, class TElemHandler>
     276              : template <class TAttachment>
     277              : typename TAttachment::ContainerType*
     278           11 : AttachmentPipe<TElem, TElemHandler>::
     279              : get_data_container(TAttachment& attachment)
     280              : {
     281              :         AttachmentEntryIterator iter;
     282           11 :         if(m_attachmentEntryIteratorHash.get_entry(iter, attachment.id()))
     283           11 :                 return static_cast<typename TAttachment::ContainerType*>(iter->m_pContainer);
     284              :         return NULL;
     285              : }
     286              : 
     287              : template <class TElem, class TElemHandler>
     288              : void
     289              : AttachmentPipe<TElem, TElemHandler>::
     290              : defragment()
     291              : {
     292              :         if(!is_fragmented())
     293              :                 return;
     294              : 
     295              : //      if num_elements == 0, then simply resize all data-containers to 0.
     296              :         if(num_elements() == 0)
     297              :         {
     298              :         //      just clear the attachment containers.
     299              :                 for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     300              :                         iter != m_attachmentEntryContainer.end(); iter++)
     301              :                 {
     302              :                         (*iter).m_pContainer->resize(0);
     303              :                 }
     304              :                 m_stackFreeEntries = UINTStack();
     305              :                 m_numDataEntries = 0;
     306              :         }
     307              :         else
     308              :         {
     309              :         //      calculate the fragmentation array. It has to be of the same size as the fragmented data containers.
     310              :                 std::vector<uint> vNewIndices(num_data_entries(), INVALID_ATTACHMENT_INDEX);
     311              : 
     312              :         //      iterate through the elements and calculate the new index of each
     313              :                 size_t counter = 0;
     314              :                 typename atraits::element_iterator iter = atraits::elements_begin(m_pHandler);
     315              :                 typename atraits::element_iterator end = atraits::elements_end(m_pHandler);
     316              : 
     317              :                 for(; iter != end; ++iter){
     318              :                         vNewIndices[atraits::get_data_index(m_pHandler, (*iter))] = counter;
     319              :                         atraits::set_data_index(m_pHandler, (*iter), counter);
     320              :                         ++counter;
     321              :                 }
     322              : 
     323              :         //      after defragmentation there are no free indices.
     324              :                 m_stackFreeEntries = UINTStack();
     325              :                 m_numDataEntries = counter;
     326              : 
     327              :         //      now iterate through the attached data-containers and defragment each one.
     328              :                 {
     329              :                         for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     330              :                                                 iter != m_attachmentEntryContainer.end(); iter++)
     331              :                         {
     332              :                                 (*iter).m_pContainer->defragment(&vNewIndices.front(), num_elements());
     333              :                         }
     334              :                 }
     335              :         }
     336              : }
     337              : 
     338              : /*
     339              : template <class TElem, class TElemHandler>
     340              : void
     341              : AttachmentPipe<TElem, TElemHandler>::
     342              : defragment()
     343              : {
     344              :         if(!is_fragmented())
     345              :                 return;
     346              : 
     347              : //      if num_elements == 0, then simply resize all data-containers to 0.
     348              :         if(num_elements() == 0)
     349              :         {
     350              :         //      just clear the attachment containers.
     351              :                 for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     352              :                         iter != m_attachmentEntryContainer.end(); iter++)
     353              :                 {
     354              :                         (*iter).m_pContainer->resize(0);
     355              :                 }
     356              :         }
     357              :         else
     358              :         {
     359              :         //      calculate the fragmentation array. It has to be of the same size as the fragmented data containers.
     360              :                 std::vector<uint> vNewIndices(num_data_entries(), INVALID_ATTACHMENT_INDEX);
     361              : 
     362              :         //      iterate through the elements and calculate the new index of each
     363              :                 size_t counter = 0;
     364              :                 {
     365              :                         typename ElemEntryVec::iterator iter;
     366              :                         typename ElemEntryVec::iterator copyHere = m_vEntries.begin();
     367              :                         for(iter = m_vEntries.begin(); iter != m_vEntries.end(); ++iter)
     368              :                         {
     369              :                                 if(!atraits::entry_is_invalid(*iter))
     370              :                                 {
     371              :                                         vNewIndices[atraits::get_data_index(m_pHandler, (*iter))] = counter;
     372              :                                         atraits::set_data_index(m_pHandler, (*iter), counter);
     373              :                                         ++counter;
     374              : 
     375              :                                 //      copy entries
     376              :                                         *copyHere = *iter;
     377              :                                         ++copyHere;
     378              :                                 }
     379              :                         }
     380              : 
     381              :                 //      resize m_vEntries
     382              :                         m_vEntries.resize(counter);
     383              :                 }
     384              : 
     385              :         //      now iterate through the attached data-containers and defragment each one.
     386              :                 {
     387              :                         for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     388              :                                                 iter != m_attachmentEntryContainer.end(); iter++)
     389              :                         {
     390              :                                 (*iter).m_pContainer->defragment(&vNewIndices.front(), num_elements());
     391              :                         }
     392              :                 }
     393              :         }
     394              : }
     395              : */
     396              : template <class TElem, class TElemHandler>
     397              : void
     398              : AttachmentPipe<TElem, TElemHandler>::
     399              : resize_attachment_containers(size_t newSize)
     400              : {
     401              : //UG_LOG("resizing attachment containers\n");
     402              :         //PROFILE_BEGIN(AttachmentResize);
     403            7 :         m_containerSize = newSize;
     404            7 :         for(AttachmentEntryIterator iter = m_attachmentEntryContainer.begin();
     405           23 :                                 iter != m_attachmentEntryContainer.end(); iter++)
     406              :         {
     407           16 :                 (*iter).m_pContainer->resize(newSize);
     408              :         }
     409              :         //PROFILE_END();
     410              : //UG_LOG("done\n");
     411              : }
     412              : 
     413              : template <class TElem, class TElemHandler>
     414              : void
     415              : AttachmentPipe<TElem, TElemHandler>::
     416              : grow_attachment_containers(size_t newMinSize)
     417              : {
     418              :         //if(!m_attachmentEntryContainer.empty())
     419              :         {
     420              :         //      if the container-size is smaller than newMinSize, we will increase it
     421              :         //      by a factor of 2 (at least)
     422              :                 size_t actSize = get_container_size();
     423              : 
     424            7 :                 if(actSize < newMinSize)
     425              :                 {
     426            7 :                         size_t newSize = actSize * 2;
     427            7 :                         if(newSize < newMinSize)
     428              :                                 newSize = newMinSize;
     429              : 
     430              :                         resize_attachment_containers(newSize);
     431              :                 }
     432              :         }
     433              : }
     434              : 
     435              : template <class TElem, class TElemHandler>
     436              : size_t
     437              : AttachmentPipe<TElem, TElemHandler>::
     438              : get_container_size()
     439              : {
     440           18 :         return m_containerSize;
     441              : }
     442              : 
     443              : ////////////////////////////////////////////////////////////////////////
     444              : ////////////////////////////////////////////////////////////////////////
     445              : //      AttachmentAccessor
     446              : template <class TElem, class TAttachment, class TElemHandler>
     447            5 : AttachmentAccessor<TElem, TAttachment, TElemHandler>::
     448           12 : AttachmentAccessor() : m_pContainer(NULL), m_pHandler(NULL)
     449              : {
     450              : }
     451              : 
     452              : template <class TElem, class TAttachment, class TElemHandler>
     453            3 : AttachmentAccessor<TElem, TAttachment, TElemHandler>::
     454              : AttachmentAccessor(const AttachmentAccessor& aa)
     455              : {
     456           14 :         m_pContainer = aa.m_pContainer;
     457           35 :         m_pHandler = aa.m_pHandler;
     458              : }
     459              : 
     460              : template <class TElem, class TAttachment, class TElemHandler>
     461            0 : AttachmentAccessor<TElem, TAttachment, TElemHandler>::
     462              : AttachmentAccessor(AttachmentPipe<TElem, TElemHandler>& attachmentPipe, TAttachment& attachment)
     463              : {
     464            1 :         m_pContainer = static_cast<typename TAttachment::ContainerType*>(attachmentPipe.get_data_container(attachment));
     465            0 :         m_pHandler = attachmentPipe.get_elem_handler();
     466              :         assert(m_pContainer && "ERROR in AttachmentAccessor::AttachmentAccessor(attachmentPipe, attachment): attachment not attached to attachmentPipe!");
     467              : }
     468              : 
     469              : template <class TElem, class TAttachment, class TElemHandler>
     470              : bool
     471           10 : AttachmentAccessor<TElem, TAttachment, TElemHandler>::
     472              : access(AttachmentPipe<TElem, TElemHandler>& attachmentPipe, TAttachment& attachment)
     473              : {
     474           10 :         if(!attachmentPipe.has_attachment(attachment))
     475              :                 return false;
     476              : 
     477           10 :         m_pContainer = static_cast<typename TAttachment::ContainerType*>(attachmentPipe.get_data_container(attachment));
     478           10 :         m_pHandler = attachmentPipe.get_elem_handler();
     479              :         assert(m_pContainer && "ERROR in AttachmentAccessor::access(attachmentPipe, attachment): attachment not attached to attachmentPipe!");
     480              : 
     481           10 :         return true;
     482              : }
     483              : 
     484              : }//     end of namespace
     485              : 
     486              : #endif
        

Generated by: LCOV version 2.0-1