LCOV - code coverage report
Current view: top level - ugbase/lib_grid/grid - grid.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 12.3 % 513 63
Test Date: 2025-09-21 23:31:46 Functions: 15.4 % 91 14

            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              : #include <cassert>
      34              : #include <algorithm>
      35              : #include "grid.h"
      36              : #include "grid_util.h"
      37              : #include "common/common.h"
      38              : #include "lib_grid/attachments/attached_list.h"
      39              : #include "lib_grid/tools/periodic_boundary_manager.h"
      40              : 
      41              : #ifdef UG_PARALLEL
      42              : #include "lib_grid/parallelization/distributed_grid.h"
      43              : #endif
      44              : 
      45              : 
      46              : using namespace std;
      47              : 
      48              : namespace ug
      49              : {
      50              : ////////////////////////////////////////////////////////////////////////////////////////////////
      51              : ////////////////////////////////////////////////////////////////////////////////////////////////
      52              : //      implementation of Grid
      53              : 
      54              : ////////////////////////////////////////////////////////////////////////
      55              : //      constructors
      56            1 : Grid::Grid() :
      57              :         m_aVertexContainer("Grid_VertexContainer", false),
      58              :         m_aEdgeContainer("Grid_EdgeContainer", false),
      59              :         m_aFaceContainer("Grid_FaceContainer", false),
      60              :         m_aVolumeContainer("Grid_VolumeContainer", false),
      61            1 :         m_bMarking(false),
      62              :         m_aMark("Grid_Mark", false),
      63            1 :         m_distGridMgr(NULL),
      64            1 :         m_periodicBndMgr(NULL)
      65              : {
      66            1 :         m_hashCounter = 0;
      67            1 :         m_currentMark = 0;
      68            1 :         m_options = GRIDOPT_NONE;
      69            2 :         m_messageHub = SPMessageHub(new MessageHub());
      70              : 
      71            1 :         change_options(GRIDOPT_DEFAULT);
      72            1 : }
      73              : 
      74            0 : Grid::Grid(uint options) :
      75              :         m_aVertexContainer("Grid_VertexContainer", false),
      76              :         m_aEdgeContainer("Grid_EdgeContainer", false),
      77              :         m_aFaceContainer("Grid_FaceContainer", false),
      78              :         m_aVolumeContainer("Grid_VolumeContainer", false),
      79            0 :         m_bMarking(false),
      80              :         m_aMark("Grid_Mark", false),
      81            0 :         m_distGridMgr(NULL),
      82            0 :         m_periodicBndMgr(NULL)
      83              : {
      84            0 :         m_hashCounter = 0;
      85            0 :         m_currentMark = 0;
      86            0 :         m_options = GRIDOPT_NONE;
      87            0 :         m_messageHub = SPMessageHub(new MessageHub());
      88              : 
      89            0 :         change_options(options);
      90            0 : }
      91              : 
      92            0 : Grid::Grid(const Grid& grid) :
      93              :         m_aVertexContainer("Grid_VertexContainer", false),
      94              :         m_aEdgeContainer("Grid_EdgeContainer", false),
      95              :         m_aFaceContainer("Grid_FaceContainer", false),
      96              :         m_aVolumeContainer("Grid_VolumeContainer", false),
      97            0 :         m_bMarking(false),
      98              :         m_aMark("Grid_Mark", false),
      99            0 :         m_distGridMgr(NULL),
     100            0 :         m_periodicBndMgr(NULL)
     101              : {
     102            0 :         m_hashCounter = 0;
     103            0 :         m_currentMark = 0;
     104            0 :         m_options = GRIDOPT_NONE;
     105            0 :         m_messageHub = SPMessageHub(new MessageHub());
     106              : 
     107            0 :         assign_grid(grid);
     108            0 : }
     109              : 
     110            1 : Grid::~Grid()
     111              : {
     112            1 :         notify_and_clear_observers_on_grid_destruction();
     113              : 
     114              : //      erase all elements
     115            1 :         clear_geometry();
     116              : 
     117              : //      remove marks - would be done anyway...
     118            1 :         remove_marks();
     119              : 
     120              : //      erase any internal managers and handlers
     121              :         #ifdef UG_PARALLEL
     122              :                 if(m_distGridMgr)                       delete m_distGridMgr;
     123              :         #endif
     124              : 
     125            1 :         if(m_periodicBndMgr)            delete m_periodicBndMgr;
     126            1 : }
     127              : 
     128            1 : void Grid::notify_and_clear_observers_on_grid_destruction(GridObserver* initiator)
     129              : {
     130              : //      tell registered grid-observers that the grid is to be destroyed.
     131              : //      do this in reverse order, so that the danger of accessing invalid observers
     132              : //      is minimized.
     133              :         for(ObserverContainer::reverse_iterator iter = m_gridObservers.rbegin();
     134            1 :                 iter != m_gridObservers.rend(); ++iter)
     135              :         {
     136            0 :                 if(*iter != initiator)
     137            0 :                         (*iter)->grid_to_be_destroyed(this);
     138              :         }
     139              : 
     140              : //      unregister all observers        
     141            1 :         while(!m_gridObservers.empty())
     142            0 :                 unregister_observer(m_gridObservers.back());
     143              :         
     144            1 :         while(!m_vertexObservers.empty())
     145            0 :                 unregister_observer(m_vertexObservers.back());
     146              : 
     147            1 :         while(!m_edgeObservers.empty())
     148            0 :                 unregister_observer(m_edgeObservers.back());
     149              : 
     150            1 :         while(!m_faceObservers.empty())
     151            0 :                 unregister_observer(m_faceObservers.back());
     152              : 
     153            1 :         while(!m_volumeObservers.empty())
     154            0 :                 unregister_observer(m_volumeObservers.back());
     155            1 : }
     156              : 
     157            0 : void Grid::
     158              : set_parallel(bool parallel)
     159              : {
     160            0 :         if(parallel){
     161              :                 #ifdef UG_PARALLEL
     162              :                         if(!is_parallel()){
     163              :                         //      we currently only support parallel mutli-grids, sadly...
     164              :                                 MultiGrid* mg = dynamic_cast<MultiGrid*>(this);
     165              :                                 if(mg){
     166              :                                         if(m_distGridMgr) delete m_distGridMgr;
     167              :                                         m_distGridMgr = new DistributedGridManager;
     168              :                                         m_distGridMgr->assign(*mg);
     169              :                                 }
     170              :                                 else{
     171              :                                         UG_THROW("Error during Grid::set_parallel: "
     172              :                                                         "The DistributedGridManager can currently only be used to "
     173              :                                                         "parallelize ug::MultiGrid. ug::Grid can currently not be used "
     174              :                                                         "for parallel computations. Sorry.");
     175              :                                 }
     176              :                         }
     177              :                 #else
     178            0 :                         UG_THROW("Parallelism can only be activated, if ug was compiled with "
     179              :                                         "PARALLEL=ON. This is not the case for this application.");
     180              :                 #endif
     181              :         }
     182              :         else if(is_parallel()){
     183              :                 #ifdef UG_PARALLEL
     184              :                         if(m_distGridMgr) delete m_distGridMgr;
     185              :                         m_distGridMgr = NULL;
     186              :                 #endif
     187              :         }
     188            0 : }
     189              : 
     190            0 : void Grid::set_periodic_boundaries(bool is_periodic)
     191              : {
     192            0 :         if(is_periodic)
     193              :         {
     194            0 :                 if(m_periodicBndMgr) delete m_periodicBndMgr;
     195            0 :                 m_periodicBndMgr = new PeriodicBoundaryManager();
     196            0 :                 m_periodicBndMgr->set_grid(this);
     197              :         }
     198            0 :         else if(m_periodicBndMgr){
     199            0 :                 delete m_periodicBndMgr;
     200            0 :                 m_periodicBndMgr = NULL;
     201              :         }
     202            0 : }
     203              : 
     204            0 : bool Grid::has_periodic_boundaries() const
     205              : {
     206            0 :         return m_periodicBndMgr != NULL;
     207              : }
     208              : 
     209            0 : PeriodicBoundaryManager* Grid::periodic_boundary_manager()
     210              : {
     211            0 :         return m_periodicBndMgr;
     212              : }
     213              : 
     214            0 : const PeriodicBoundaryManager* Grid::periodic_boundary_manager() const
     215              : {
     216            0 :         return m_periodicBndMgr;
     217              : }
     218              : 
     219              : 
     220            0 : void Grid::clear()
     221              : {
     222            0 :         clear_geometry();
     223            0 :         clear_attachments();
     224            0 : }
     225              : 
     226            1 : void Grid::clear_geometry()
     227              : {
     228              : //      disable all options to speed it up
     229            1 :         uint opts = get_options();
     230            1 :         set_options(GRIDOPT_NONE);
     231              :         
     232              :         clear<Volume>();
     233              :         clear<Face>();
     234              :         clear<Edge>();
     235              :         clear<Vertex>();
     236              :         
     237              : //      reset options
     238            1 :         set_options(opts);
     239            1 : }
     240              : 
     241              : template <class TElem>
     242            0 : void Grid::clear_attachments()
     243              : {
     244              :         typedef typename traits<TElem>::AttachmentPipe    AttachmentPipe;
     245              : 
     246              :         vector<AttachmentEntry>   vEntries;
     247              : 
     248              : //      iterate through all attachment pipes
     249              :         AttachmentPipe& ap = get_attachment_pipe<TElem>();
     250              : 
     251              : //      collect all attachment entries
     252            0 :         for(typename AttachmentPipe::ConstAttachmentEntryIterator iter = ap.attachments_begin();
     253            0 :                 iter != ap.attachments_end(); ++iter)
     254              :         {
     255            0 :                         vEntries.push_back(*iter);
     256              :         }
     257              : 
     258              : //      iterate through the entries in the vector and delete the ones
     259              : //      that have an enabled pass-on behaviour
     260            0 :         for(size_t j = 0; j < vEntries.size(); ++j)
     261              :         {
     262              :                 const AttachmentEntry& ae = vEntries[j];
     263              :                 
     264            0 :                 if(ae.m_userData == 1){
     265            0 :                         ap.detach(*ae.m_pAttachment);
     266              :                 }
     267              :         }
     268            0 : }
     269              : 
     270            0 : void Grid::clear_attachments()
     271              : {
     272            0 :         clear_attachments<Vertex>();
     273            0 :         clear_attachments<Edge>();
     274            0 :         clear_attachments<Face>();
     275            0 :         clear_attachments<Volume>();
     276            0 : }
     277              : 
     278            0 : Grid& Grid::operator = (const Grid& grid)
     279              : {
     280              : //      clears the grid and calls assign_grid afterwards.
     281              : //      we're disabling any options, since new options will
     282              : //      be set during assign_grid anyway. This might speed
     283              : //      things up a little
     284            0 :         set_options(GRIDOPT_NONE);
     285            0 :         clear_geometry();
     286            0 :         assign_grid(grid);
     287              :         
     288            0 :         return *this;
     289              : }
     290              : 
     291              : template <class TAttachmentPipe>
     292            0 : void Grid::copy_user_attachments(const TAttachmentPipe& apSrc, TAttachmentPipe& apDest,
     293              :                                                                 vector<int>& srcDataIndices)
     294              : {
     295            0 :         for(typename TAttachmentPipe::ConstAttachmentEntryIterator iter = apSrc.attachments_begin();
     296            0 :                 iter != apSrc.attachments_end(); ++iter)
     297              :         {
     298              :                 const AttachmentEntry& ae = *iter;
     299            0 :                 if(ae.m_userData == 1){
     300              :                 //      attach the attachment to this grid
     301            0 :                         apDest.attach(*ae.m_pAttachment, ae.m_userData);
     302            0 :                         const IAttachmentDataContainer& conSrc = *ae.m_pContainer;
     303            0 :                         IAttachmentDataContainer& conDest = *apDest.get_data_container(*ae.m_pAttachment);
     304              : 
     305              :                 //      we use the containers copy-method
     306            0 :                         conSrc.copy_to_container(&conDest, &srcDataIndices.front(),
     307              :                                                                          (int)srcDataIndices.size());
     308              :                 }
     309              :         }
     310            0 : }
     311              : 
     312            0 : void Grid::assign_grid(const Grid& grid)
     313              : {
     314              : //TODO: notify a grid observer that copying has started
     315              : 
     316              : //      we need a vertex-map that allows us to find a vertex in the new grid
     317              : //      given a vertex in the old one.
     318            0 :         vector<Vertex*>   vrtMap(grid.attachment_container_size<Vertex>(), NULL);
     319              : 
     320              : //      we need index-lists that allow us to copy attachments later on
     321            0 :         vector<int> vSrcDataIndex[NUM_GEOMETRIC_BASE_OBJECTS];
     322              :         vector<int>& vSrcDataIndexVRT = vSrcDataIndex[VERTEX];
     323              :         vector<int>& vSrcDataIndexEDGE = vSrcDataIndex[EDGE];
     324              :         vector<int>& vSrcDataIndexFACE = vSrcDataIndex[FACE];
     325              :         vector<int>& vSrcDataIndexVOL = vSrcDataIndex[VOLUME];
     326              : 
     327              : //      copy all vertices
     328            0 :         vSrcDataIndexVRT.resize(grid.num<Vertex>());
     329              :         ConstVertexIterator vrtsEnd = grid.end<Vertex>();
     330            0 :         for(ConstVertexIterator iter = grid.begin<Vertex>(); iter != vrtsEnd; ++iter)
     331              :         {
     332              :                 Vertex* vrt = *iter;
     333            0 :                 Vertex* nVrt = *create_by_cloning(vrt);
     334            0 :                 vrtMap[grid.get_attachment_data_index(vrt)] = nVrt;
     335            0 :                 vSrcDataIndexVRT[get_attachment_data_index(nVrt)] = grid.get_attachment_data_index(vrt);
     336              :         }
     337              : 
     338              : //      copy all edges
     339            0 :         vSrcDataIndexEDGE.resize(grid.num<Edge>());
     340              :         ConstEdgeIterator edgesEnd = grid.end<Edge>();
     341            0 :         for(ConstEdgeIterator iter = grid.begin<Edge>(); iter != edgesEnd; ++iter)
     342              :         {
     343              :                 Edge* e = *iter;
     344            0 :                 Edge* nE = *create_by_cloning(e, EdgeDescriptor(
     345            0 :                                                                                         vrtMap[grid.get_attachment_data_index(e->vertex(0))],
     346            0 :                                                                                         vrtMap[grid.get_attachment_data_index(e->vertex(1))]));
     347            0 :                 vSrcDataIndexEDGE[get_attachment_data_index(nE)] = grid.get_attachment_data_index(e);
     348              :         }
     349              : 
     350              : //      copy all faces
     351            0 :         vSrcDataIndexFACE.resize(grid.num<Face>());
     352            0 :         FaceDescriptor fd;
     353              :         ConstFaceIterator facesEnd = grid.end<Face>();
     354            0 :         for(ConstFaceIterator iter = grid.begin<Face>(); iter != facesEnd; ++iter)
     355              :         {
     356              :                 Face* f = *iter;
     357            0 :                 uint numVrts = f->num_vertices();
     358            0 :                 Face::ConstVertexArray vrts = f->vertices();
     359              : 
     360              :         //      fill the face descriptor
     361            0 :                 if(numVrts != fd.num_vertices())
     362              :                         fd.set_num_vertices(numVrts);
     363              :                 
     364            0 :                 for(uint i = 0; i < numVrts; ++i)
     365            0 :                         fd.set_vertex(i, vrtMap[grid.get_attachment_data_index(vrts[i])]);
     366              : 
     367              :         //      create the new face
     368            0 :                 Face* nF = *create_by_cloning(f, fd);
     369              : 
     370            0 :                 vSrcDataIndexFACE[get_attachment_data_index(nF)] = grid.get_attachment_data_index(f);
     371              :         }
     372              : 
     373              : //      copy all volumes
     374            0 :         vSrcDataIndexVOL.resize(grid.num<Volume>());
     375            0 :         VolumeDescriptor vd;
     376              :         ConstVolumeIterator volsEnd = grid.end<Volume>();
     377            0 :         for(ConstVolumeIterator iter = grid.begin<Volume>(); iter != volsEnd; ++iter)
     378              :         {
     379              :                 Volume* v = *iter;
     380            0 :                 uint numVrts = v->num_vertices();
     381            0 :                 Volume::ConstVertexArray vrts = v->vertices();
     382              : 
     383              :         //      fill the volume descriptor
     384            0 :                 if(numVrts != vd.num_vertices())
     385              :                         vd.set_num_vertices(numVrts);
     386              : 
     387            0 :                 for(uint i = 0; i < numVrts; ++i)
     388            0 :                         vd.set_vertex(i, vrtMap[grid.get_attachment_data_index(vrts[i])]);
     389              : 
     390              :         //      create the volume
     391            0 :                 Volume* nV = *create_by_cloning(v, vd);
     392              : 
     393            0 :                 vSrcDataIndexVOL[get_attachment_data_index(nV)] = grid.get_attachment_data_index(v);
     394              :         }
     395              : 
     396              : //      enable options
     397            0 :         enable_options(grid.get_options());
     398              : 
     399              : //      copy attachments that may be passed on
     400            0 :         copy_user_attachments(grid.m_vertexElementStorage.m_attachmentPipe,
     401            0 :                                         m_vertexElementStorage.m_attachmentPipe, vSrcDataIndexVRT);
     402            0 :         copy_user_attachments(grid.m_edgeElementStorage.m_attachmentPipe,
     403            0 :                                         m_edgeElementStorage.m_attachmentPipe, vSrcDataIndexEDGE);
     404            0 :         copy_user_attachments(grid.m_faceElementStorage.m_attachmentPipe,
     405            0 :                                         m_faceElementStorage.m_attachmentPipe, vSrcDataIndexFACE);
     406            0 :         copy_user_attachments(grid.m_volumeElementStorage.m_attachmentPipe,
     407            0 :                                         m_volumeElementStorage.m_attachmentPipe, vSrcDataIndexVOL);
     408              : 
     409              : //      parallelism
     410            0 :         if(grid.is_parallel()){
     411            0 :                 set_parallel(true);
     412              :         //todo: copy interfaces from grid.
     413              :         }
     414              : 
     415              : //TODO: notify a grid observer that copying has ended
     416            0 : }
     417              : 
     418              : 
     419            0 : VertexIterator Grid::create_by_cloning(Vertex* pCloneMe, GridObject* pParent)
     420              : {
     421            0 :         Vertex* pNew = reinterpret_cast<Vertex*>(pCloneMe->create_empty_instance());
     422            0 :         register_vertex(pNew, pParent);
     423            0 :         return iterator_cast<VertexIterator>(get_iterator(pNew));
     424              : }
     425              : 
     426            0 : EdgeIterator Grid::create_by_cloning(Edge* pCloneMe, const IVertexGroup& ev, GridObject* pParent)
     427              : {
     428            0 :         Edge* pNew = reinterpret_cast<Edge*>(pCloneMe->create_empty_instance());
     429            0 :         pNew->set_vertex(0, ev.vertex(0));
     430            0 :         pNew->set_vertex(1, ev.vertex(1));
     431            0 :         register_edge(pNew, pParent);
     432            0 :         return iterator_cast<EdgeIterator>(get_iterator(pNew));
     433              : }
     434              : 
     435            0 : FaceIterator Grid::create_by_cloning(Face* pCloneMe, const IVertexGroup& fv, GridObject* pParent)
     436              : {
     437            0 :         Face* pNew = reinterpret_cast<Face*>(pCloneMe->create_empty_instance());
     438            0 :         uint numVrts = fv.num_vertices();
     439            0 :         Face::ConstVertexArray vrts = fv.vertices();
     440            0 :         for(uint i = 0; i < numVrts; ++i)
     441            0 :                 pNew->set_vertex(i, vrts[i]);
     442            0 :         register_face(pNew, pParent);
     443            0 :         return iterator_cast<FaceIterator>(get_iterator(pNew));
     444              : }
     445              : 
     446            0 : VolumeIterator Grid::create_by_cloning(Volume* pCloneMe, const IVertexGroup& vv, GridObject* pParent)
     447              : {
     448            0 :         Volume* pNew = reinterpret_cast<Volume*>(pCloneMe->create_empty_instance());
     449            0 :         uint numVrts = vv.num_vertices();
     450            0 :         Volume::ConstVertexArray vrts = vv.vertices();
     451            0 :         for(uint i = 0; i < numVrts; ++i)
     452            0 :                 pNew->set_vertex(i, vrts[i]);
     453            0 :         register_volume(pNew, pParent);
     454            0 :         return iterator_cast<VolumeIterator>(get_iterator(pNew));
     455              : }
     456              : 
     457              : ////////////////////////////////////////////////////////////////////////
     458              : //      erase functions
     459            0 : void Grid::erase(GridObject* geomObj)
     460              : {
     461              :         assert(geomObj->container_section() != -1
     462              :                         && "ERROR in Grid::erase(Vertex*). Invalid pipe section!");
     463              : 
     464            0 :         uint objType = geomObj->base_object_id();
     465            0 :         switch(objType)
     466              :         {
     467              :                 case VERTEX:
     468            0 :                         erase(dynamic_cast<Vertex*>(geomObj));
     469            0 :                         break;
     470              :                 case EDGE:
     471            0 :                         erase(dynamic_cast<Edge*>(geomObj));
     472            0 :                         break;
     473              :                 case FACE:
     474            0 :                         erase(dynamic_cast<Face*>(geomObj));
     475            0 :                         break;
     476              :                 case VOLUME:
     477            0 :                         erase(dynamic_cast<Volume*>(geomObj));
     478            0 :                         break;
     479              :         };
     480            0 : }
     481              : 
     482            3 : void Grid::erase(Vertex* vrt)
     483              : {
     484              :         assert((vrt != NULL) && "ERROR in Grid::erase(Vertex*): invalid pointer)");
     485              :         assert(vrt->container_section() != -1
     486              :                         && "ERROR in Grid::erase(Vertex*). Invalid pipe section!");
     487              : 
     488            3 :         unregister_vertex(vrt);
     489              : 
     490            3 :         delete vrt;
     491            3 : }
     492              : 
     493            3 : void Grid::erase(Edge* edge)
     494              : {
     495              :         assert((edge != NULL) && "ERROR in Grid::erase(Edge*): invalid pointer)");
     496              :         assert(edge->container_section() != -1
     497              :                         && "ERROR in Grid::erase(Edge*). Invalid pipe section!");
     498              : 
     499            3 :         unregister_edge(edge);
     500              : 
     501            3 :         delete edge;
     502            3 : }
     503              : 
     504            1 : void Grid::erase(Face* face)
     505              : {
     506              :         assert((face != NULL) && "ERROR in Grid::erase(Face*): invalid pointer)");
     507              :         assert(face->container_section() != -1
     508              :                         && "ERROR in Grid::erase(Face*). Invalid pipe section!");
     509              : 
     510            1 :         unregister_face(face);
     511              : 
     512            1 :         delete face;
     513            1 : }
     514              : 
     515            0 : void Grid::erase(Volume* vol)
     516              : {
     517              :         assert((vol != NULL) && "ERROR in Grid::erase(Volume*): invalid pointer)");
     518              :         assert(vol->container_section() != -1
     519              :                         && "ERROR in Grid::erase(Volume*). Invalid pipe section!");
     520              : 
     521            0 :         unregister_volume(vol);
     522              : 
     523            0 :         delete vol;
     524            0 : }
     525              : 
     526              : //      the geometric-object-collection:
     527            0 : GridObjectCollection Grid::get_grid_objects()
     528              : {
     529              :         return GridObjectCollection(&m_vertexElementStorage.m_sectionContainer,
     530              :                                                                          &m_edgeElementStorage.m_sectionContainer,
     531              :                                                                          &m_faceElementStorage.m_sectionContainer,
     532            0 :                                                                          &m_volumeElementStorage.m_sectionContainer);
     533              : }
     534              : 
     535            0 : void Grid::flip_orientation(Edge* e)
     536              : {
     537              :         swap(e->m_vertices[0], e->m_vertices[1]);
     538            0 : }
     539              : 
     540            0 : void Grid::flip_orientation(Face* f)
     541              : {
     542              : //      inverts the order of vertices.
     543            0 :         uint numVrts = (int)f->num_vertices();
     544            0 :         vector<Vertex*> vVrts(numVrts);
     545              :         
     546              :         uint i;
     547            0 :         for(i = 0; i < numVrts; ++i)
     548            0 :                 vVrts[i] = f->vertex(i);
     549              :                 
     550            0 :         for(i = 0; i < numVrts; ++i)
     551            0 :                 f->set_vertex(i, vVrts[numVrts - 1 - i]);
     552              : 
     553              : //      update associated edge list
     554            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES)){
     555              :                 m_aaEdgeContainerFACE[f].clear();
     556            0 :                 EdgeDescriptor ed;
     557            0 :                 for(size_t ind = 0; ind < f->num_edges(); ++ind){
     558              :                 //      get the descriptor of the i-th edge
     559            0 :                         f->edge_desc(ind, ed);
     560              :                 //      find the edge by checking vertices.
     561            0 :                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
     562            0 :                         if(e)
     563            0 :                                 m_aaEdgeContainerFACE[f].push_back(e);
     564              :                 }
     565              :         }
     566            0 : }
     567              : 
     568            0 : void Grid::flip_orientation(Volume* vol)
     569              : {
     570              : //      flips the orientation of volumes
     571              : //      get the descriptor for the flipped volume
     572            0 :         VolumeDescriptor vd;
     573            0 :         vol->get_flipped_orientation(vd);
     574              :         
     575              : //      change vertex order of the original volume
     576            0 :         size_t numVrts = vol->num_vertices();
     577            0 :         for(size_t i = 0; i < numVrts; ++i)
     578            0 :                 vol->set_vertex(i, vd.vertex(i));
     579              : 
     580              : //      update associated edge list
     581            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)){
     582              :                 m_aaEdgeContainerVOLUME[vol].clear();
     583            0 :                 EdgeDescriptor ed;
     584            0 :                 for(size_t ind = 0; ind < vol->num_edges(); ++ind){
     585              :                 //      get the descriptor of the i-th edge
     586            0 :                         vol->edge_desc(ind, ed);
     587              :                 //      find the edge by checking vertices.
     588            0 :                         Edge* e = find_edge_in_associated_edges(ed.vertex(0), ed);
     589            0 :                         if(e)
     590            0 :                                 m_aaEdgeContainerVOLUME[vol].push_back(e);
     591              :                 }
     592              :         }
     593              : 
     594              : //      update associated face list
     595            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES)){
     596              :                 m_aaFaceContainerVOLUME[vol].clear();
     597            0 :                 FaceDescriptor fd;
     598            0 :                 for(size_t ind = 0; ind < vol->num_faces(); ++ind){
     599              :                 //      get the descriptor of the i-th face
     600            0 :                         vol->face_desc(ind, fd);
     601              :                 //      find the face by checking vertices.
     602            0 :                         Face* f = find_face_in_associated_faces(fd.vertex(0), fd);
     603            0 :                         if(f)
     604            0 :                                 m_aaFaceContainerVOLUME[vol].push_back(f);
     605              :                 }
     606              :         }
     607            0 : }
     608              : 
     609            0 : size_t Grid::vertex_fragmentation()
     610              : {
     611            0 :         return m_vertexElementStorage.m_attachmentPipe.num_data_entries() - m_vertexElementStorage.m_attachmentPipe.num_elements();
     612              : }
     613              : 
     614            0 : size_t Grid::edge_fragmentation()
     615              : {
     616            0 :         return m_edgeElementStorage.m_attachmentPipe.num_data_entries() - m_edgeElementStorage.m_attachmentPipe.num_elements();
     617              : }
     618              : 
     619            0 : size_t Grid::face_fragmentation()
     620              : {
     621            0 :         return m_faceElementStorage.m_attachmentPipe.num_data_entries() - m_faceElementStorage.m_attachmentPipe.num_elements();
     622              : }
     623              : 
     624            0 : size_t Grid::volume_fragmentation()
     625              : {
     626            0 :         return m_volumeElementStorage.m_attachmentPipe.num_data_entries() - m_volumeElementStorage.m_attachmentPipe.num_elements();
     627              : }
     628              : 
     629              : 
     630            0 : GridObject* Grid::
     631              : get_opposing_object(Vertex* vrt, Face* elem)
     632              : {
     633            0 :         std::pair<GridBaseObjectId, int> id = elem->get_opposing_object(vrt);
     634            0 :         switch(id.first){
     635            0 :                 case VERTEX:
     636            0 :                         return elem->vertex(id.second);
     637            0 :                 case EDGE:
     638            0 :                         return get_edge(elem, id.second);
     639            0 :                 default:
     640            0 :                         UG_THROW("Unsupported geometric base object type returned by "
     641              :                                         "Face::get_opposing_object(vrt)");
     642              :         }
     643              : }
     644              : 
     645            0 : GridObject* Grid::
     646              : get_opposing_object(Vertex* vrt, Volume* elem)
     647              : {
     648            0 :         std::pair<GridBaseObjectId, int> id = elem->get_opposing_object(vrt);
     649            0 :         switch(id.first){
     650            0 :                 case VERTEX:
     651            0 :                         return elem->vertex(id.second);
     652            0 :                 case EDGE:
     653            0 :                         return get_edge(elem, id.second);
     654            0 :                 case FACE:
     655            0 :                         return get_face(elem, id.second);
     656            0 :                 default:
     657            0 :                         UG_THROW("Unsupported geometric base object type returned by "
     658              :                                         "Volume::get_opposing_object(vrt)");
     659              :         }
     660              : }
     661              : 
     662              : 
     663              : ////////////////////////////////////////////////////////////////////////
     664              : //      pass_on_values
     665              : template <class TAttachmentPipe, class TElem>
     666              : void Grid::pass_on_values(TAttachmentPipe& attachmentPipe,
     667              :                                                         TElem* pSrc, TElem* pDest)
     668              : {
     669            0 :         for(typename TAttachmentPipe::ConstAttachmentEntryIterator
     670              :                         iter = attachmentPipe.attachments_begin();
     671            0 :                 iter != attachmentPipe.attachments_end(); iter++)
     672              :         {
     673            0 :                 if((*iter).m_userData == 1)
     674            0 :                         (*iter).m_pContainer->copy_data(get_attachment_data_index(pSrc),
     675              :                                                                                         get_attachment_data_index(pDest));
     676              :         }
     677              : }
     678              : 
     679            0 : void Grid::pass_on_values(Vertex* objSrc, Vertex* objDest)
     680              : {
     681              :         pass_on_values(m_vertexElementStorage.m_attachmentPipe, objSrc, objDest);
     682            0 : }
     683              : 
     684            0 : void Grid::pass_on_values(Edge* objSrc, Edge* objDest)
     685              : {
     686              :         pass_on_values(m_edgeElementStorage.m_attachmentPipe, objSrc, objDest);
     687            0 : }
     688              : 
     689            0 : void Grid::pass_on_values(Face* objSrc, Face* objDest)
     690              : {
     691              :         pass_on_values(m_faceElementStorage.m_attachmentPipe, objSrc, objDest);
     692            0 : }
     693              : 
     694            0 : void Grid::pass_on_values(Volume* objSrc, Volume* objDest)
     695              : {
     696              :         pass_on_values(m_volumeElementStorage.m_attachmentPipe, objSrc, objDest);
     697            0 : }
     698              : 
     699              : ////////////////////////////////////////////////////////////////////////
     700              : //      options
     701            2 : void Grid::set_options(uint options)
     702              : {
     703            2 :         change_options(options);
     704            2 : }
     705              : 
     706            1 : uint Grid::get_options() const
     707              : {
     708            1 :         return m_options;
     709              : }
     710              : 
     711            0 : void Grid::enable_options(uint options)
     712              : {
     713            0 :         change_options(m_options | options);
     714            0 : }
     715              : 
     716            0 : void Grid::disable_options(uint options)
     717              : {
     718            0 :         change_options(m_options & (~options));
     719            0 : }
     720              : 
     721           99 : bool Grid::option_is_enabled(uint option) const
     722              : {
     723           99 :         return (m_options & option) == option;
     724              : }
     725              : 
     726            3 : void Grid::change_options(uint optsNew)
     727              : {
     728            3 :         change_vertex_options(optsNew &     0x000000FF);
     729            3 :         change_edge_options(optsNew &       0x0000FF00);
     730            3 :         change_face_options(optsNew &       0x00FF0000);
     731            3 :         change_volume_options(optsNew &     0xFF000000);
     732              :         assert((m_options == optsNew) && "Grid::change_options failed");
     733            3 : }
     734              : /*
     735              : void Grid::register_observer(GridObserver* observer, uint observerType)
     736              : {
     737              : //      check which elements have to be observed and store pointers to the observers.
     738              : //      avoid double-registration!
     739              :         ObserverContainer* observerContainers[] = {&m_gridObservers, &m_vertexObservers,
     740              :                                                                                                 &m_edgeObservers, & m_faceObservers, &m_volumeObservers};
     741              : 
     742              :         uint observerTypes[] = {OT_GRID_OBSERVER, OT_VERTEX_OBSERVER, OT_EDGE_OBSERVER, OT_FACE_OBSERVER, OT_VOLUME_OBSERVER};
     743              :         for(int i = 0; i < 5; ++i)
     744              :         {
     745              :                 if((observerType & observerTypes[i]) == observerTypes[i])
     746              :                 {
     747              :                         ObserverContainer::iterator iter = find(observerContainers[i]->begin(), observerContainers[i]->end(), observer);
     748              :                         if(iter == observerContainers[i]->end())
     749              :                                 observerContainers[i]->push_back(observer);
     750              :                 }
     751              :         }
     752              : 
     753              : //      if the observer is a grid observer, notify him about the registration
     754              :         if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
     755              :                 observer->registered_at_grid(this);
     756              : }
     757              : 
     758              : void Grid::unregister_observer(GridObserver* observer)
     759              : {
     760              : //      check where the observer has been registered and erase the corresponding entries.
     761              :         ObserverContainer* observerContainers[] = {&m_gridObservers, &m_vertexObservers,
     762              :                                                                                                 &m_edgeObservers, & m_faceObservers, &m_volumeObservers};
     763              : 
     764              :         bool unregisterdFromGridObservers = false;
     765              :         for(int i = 0; i < 5; ++i)
     766              :         {
     767              :                 ObserverContainer::iterator iter = find(observerContainers[i]->begin(), observerContainers[i]->end(), observer);
     768              :                 if(iter != observerContainers[i]->end())
     769              :                 {
     770              :                         if(i == 0)
     771              :                                 unregisterdFromGridObservers = true;
     772              :                         observerContainers[i]->erase(iter);
     773              :                 }
     774              :         }
     775              : 
     776              : //      if the observer is a grid observer, notify him about the unregistration
     777              :         if(unregisterdFromGridObservers)
     778              :                 observer->unregistered_from_grid(this);
     779              : }
     780              : */
     781            0 : void Grid::register_observer(GridObserver* observer, uint observerType)
     782              : {
     783              : //      check which elements have to be observed and store pointers to the observers.
     784              : //      avoid double-registration!
     785            0 :         if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
     786              :         {
     787            0 :                 ObserverContainer::iterator iter = find(m_gridObservers.begin(),
     788              :                                                                                                 m_gridObservers.end(), observer);
     789            0 :                 if(iter == m_gridObservers.end())
     790            0 :                         m_gridObservers.push_back(observer);
     791              :         }
     792              : 
     793            0 :         if((observerType & OT_VERTEX_OBSERVER) == OT_VERTEX_OBSERVER)
     794              :         {
     795            0 :                 ObserverContainer::iterator iter = find(m_vertexObservers.begin(),
     796              :                                                                                                 m_vertexObservers.end(), observer);
     797            0 :                 if(iter == m_vertexObservers.end())
     798            0 :                         m_vertexObservers.push_back(observer);
     799              :         }
     800              : 
     801            0 :         if((observerType & OT_EDGE_OBSERVER) == OT_EDGE_OBSERVER)
     802              :         {
     803            0 :                 ObserverContainer::iterator iter = find(m_edgeObservers.begin(),
     804              :                                                                                                 m_edgeObservers.end(), observer);
     805            0 :                 if(iter == m_edgeObservers.end())
     806            0 :                         m_edgeObservers.push_back(observer);
     807              :         }
     808              : 
     809            0 :         if((observerType & OT_FACE_OBSERVER) == OT_FACE_OBSERVER)
     810              :         {
     811            0 :                 ObserverContainer::iterator iter = find(m_faceObservers.begin(),
     812              :                                                                                                 m_faceObservers.end(), observer);
     813            0 :                 if(iter == m_faceObservers.end())
     814            0 :                         m_faceObservers.push_back(observer);
     815              :         }
     816              : 
     817            0 :         if((observerType & OT_VOLUME_OBSERVER) == OT_VOLUME_OBSERVER)
     818              :         {
     819            0 :                 ObserverContainer::iterator iter = find(m_volumeObservers.begin(),
     820              :                                                                                                 m_volumeObservers.end(), observer);
     821            0 :                 if(iter == m_volumeObservers.end())
     822            0 :                         m_volumeObservers.push_back(observer);
     823              :         }
     824              : 
     825              : //      if the observer is a grid observer, notify him about the registration
     826              : //      if((observerType & OT_GRID_OBSERVER) == OT_GRID_OBSERVER)
     827              : //              observer->registered_at_grid(this);
     828            0 : }
     829              : 
     830            0 : void Grid::unregister_observer(GridObserver* observer)
     831              : {
     832              : //      check where the observer has been registered and erase the corresponding entries.
     833              :         //bool unregisterdFromGridObservers = false;
     834              : 
     835              :         {
     836            0 :                 ObserverContainer::iterator iter = find(m_gridObservers.begin(),
     837              :                                                                                                 m_gridObservers.end(), observer);
     838            0 :                 if(iter != m_gridObservers.end()){
     839            0 :                         m_gridObservers.erase(iter);
     840              :                 }
     841              : 
     842              : //              unregisterdFromGridObservers = true;
     843              :         }
     844              : 
     845              :         {
     846            0 :                 ObserverContainer::iterator iter = find(m_vertexObservers.begin(),
     847              :                                                                                                 m_vertexObservers.end(), observer);
     848            0 :                 if(iter != m_vertexObservers.end())
     849            0 :                         m_vertexObservers.erase(iter);
     850              :         }
     851              : 
     852              :         {
     853            0 :                 ObserverContainer::iterator iter = find(m_edgeObservers.begin(),
     854              :                                                                                                 m_edgeObservers.end(), observer);
     855            0 :                 if(iter != m_edgeObservers.end())
     856            0 :                         m_edgeObservers.erase(iter);
     857              :         }
     858              : 
     859              :         {
     860            0 :                 ObserverContainer::iterator iter = find(m_faceObservers.begin(),
     861              :                                                                                                 m_faceObservers.end(), observer);
     862            0 :                 if(iter != m_faceObservers.end())
     863            0 :                         m_faceObservers.erase(iter);
     864              :         }
     865              : 
     866              :         {
     867            0 :                 ObserverContainer::iterator iter = find(m_volumeObservers.begin(),
     868              :                                                                                                 m_volumeObservers.end(), observer);
     869            0 :                 if(iter != m_volumeObservers.end())
     870            0 :                         m_volumeObservers.erase(iter);
     871              :         }
     872              : 
     873              : //      if the observer is a grid observer, notify him about the unregistration
     874              : //      if(unregisterdFromGridObservers)
     875              : //              observer->unregistered_from_grid(this);
     876              : 
     877            0 : }
     878              : 
     879              : 
     880              : ////////////////////////////////////////////////////////////////////////
     881              : //      associated edge access
     882            3 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Vertex* vrt)
     883              : {
     884            3 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     885              :         {
     886              :                 LOG("WARNING in associated_edges_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
     887            0 :                 vertex_store_associated_edges(true);
     888              :         }
     889            3 :         return m_aaEdgeContainerVERTEX[vrt].begin();
     890              : }
     891              : 
     892            3 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Vertex* vrt)
     893              : {
     894            3 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
     895              :         {
     896              :                 LOG("WARNING in associated_edges_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES." << endl);
     897            0 :                 vertex_store_associated_edges(true);
     898              :         }
     899            3 :         return m_aaEdgeContainerVERTEX[vrt].end();
     900              : }
     901              : 
     902            0 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Face* face)
     903              : {
     904            0 :         if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
     905              :         {
     906              :                 LOG("WARNING in associated_edges_begin(face): auto-enabling FACEOPT_STORE_ASSOCIATED_EDGES." << endl);
     907            0 :                 face_store_associated_edges(true);
     908              :         }
     909            0 :         return m_aaEdgeContainerFACE[face].begin();
     910              : }
     911              : 
     912            0 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Face* face)
     913              : {
     914            0 :         if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
     915              :         {
     916              :                 LOG("WARNING in associated_edges_end(face): auto-enabling FACEOPT_STORE_ASSOCIATED_EDGES." << endl);
     917            0 :                 face_store_associated_edges(true);
     918              :         }
     919            0 :         return m_aaEdgeContainerFACE[face].end();
     920              : }
     921              : 
     922            0 : Grid::AssociatedEdgeIterator Grid::associated_edges_begin(Volume* vol)
     923              : {
     924            0 :         if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
     925              :         {
     926              :                 LOG("WARNING in associated_edges_begin(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_EDGES." << endl);
     927            0 :                 volume_store_associated_edges(true);
     928              :         }
     929            0 :         return m_aaEdgeContainerVOLUME[vol].begin();
     930              : }
     931              : 
     932            0 : Grid::AssociatedEdgeIterator Grid::associated_edges_end(Volume* vol)
     933              : {
     934            0 :         if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
     935              :         {
     936              :                 LOG("WARNING in associated_edges_end(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_EDGES." << endl);
     937            0 :                 volume_store_associated_edges(true);
     938              :         }
     939            0 :         return m_aaEdgeContainerVOLUME[vol].end();
     940              : }
     941              : 
     942              : ////////////////////////////////////////////////////////////////////////
     943              : //      associated face access
     944            0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Vertex* vrt)
     945              : {
     946            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     947              :         {
     948              :                 LOG("WARNING in associated_faces_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
     949            0 :                 vertex_store_associated_faces(true);
     950              :         }
     951            0 :         return m_aaFaceContainerVERTEX[vrt].begin();
     952              : }
     953              : 
     954            0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Vertex* vrt)
     955              : {
     956            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))
     957              :         {
     958              :                 LOG("WARNING in associated_faces_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_FACES." << endl);
     959            0 :                 vertex_store_associated_faces(true);
     960              :         }
     961            0 :         return m_aaFaceContainerVERTEX[vrt].end();
     962              : }
     963              : 
     964            0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Edge* edge)
     965              : {
     966            0 :         if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     967              :         {
     968              :                 LOG("WARNING in associated_faces_begin(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_FACES." << endl);
     969            0 :                 edge_store_associated_faces(true);
     970              :         }
     971            0 :         return m_aaFaceContainerEDGE[edge].begin();
     972              : }
     973              : 
     974            0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Edge* edge)
     975              : {
     976            0 :         if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_FACES))
     977              :         {
     978              :                 LOG("WARNING in associated_faces_end(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_FACES." << endl);
     979            0 :                 edge_store_associated_faces(true);
     980              :         }
     981            0 :         return m_aaFaceContainerEDGE[edge].end();
     982              : }
     983              : 
     984            0 : Grid::AssociatedFaceIterator Grid::associated_faces_begin(Volume* vol)
     985              : {
     986            0 :         if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
     987              :         {
     988              :                 LOG("WARNING in associated_faces_begin(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_FACES." << endl);
     989            0 :                 volume_store_associated_faces(true);
     990              :         }
     991            0 :         return m_aaFaceContainerVOLUME[vol].begin();
     992              : }
     993              : 
     994            0 : Grid::AssociatedFaceIterator Grid::associated_faces_end(Volume* vol)
     995              : {
     996            0 :         if(!option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
     997              :         {
     998              :                 LOG("WARNING in associated_faces_end(vol): auto-enabling VOLOPT_STORE_ASSOCIATED_FACES." << endl);
     999            0 :                 volume_store_associated_faces(true);
    1000              :         }
    1001            0 :         return m_aaFaceContainerVOLUME[vol].end();
    1002              : }
    1003              : 
    1004              : ////////////////////////////////////////////////////////////////////////
    1005              : //      associated volume access
    1006            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Vertex* vrt)
    1007              : {
    1008            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    1009              :         {
    1010              :                 LOG("WARNING in associated_volumes_begin(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1011            0 :                 vertex_store_associated_volumes(true);
    1012              :         }
    1013            0 :         return m_aaVolumeContainerVERTEX[vrt].begin();
    1014              : }
    1015              : 
    1016            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Vertex* vrt)
    1017              : {
    1018            0 :         if(!option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))
    1019              :         {
    1020              :                 LOG("WARNING in associated_volumes_end(vrt): auto-enabling VRTOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1021            0 :                 vertex_store_associated_volumes(true);
    1022              :         }
    1023            0 :         return m_aaVolumeContainerVERTEX[vrt].end();
    1024              : }
    1025              : 
    1026            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Edge* edge)
    1027              : {
    1028            0 :         if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    1029              :         {
    1030              :                 LOG("WARNING in associated_volumes_begin(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1031            0 :                 edge_store_associated_volumes(true);
    1032              :         }
    1033            0 :         return m_aaVolumeContainerEDGE[edge].begin();
    1034              : }
    1035              : 
    1036            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Edge* edge)
    1037              : {
    1038            0 :         if(!option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES))
    1039              :         {
    1040              :                 LOG("WARNING in associated_volumes_end(edge): auto-enabling EDGEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1041            0 :                 edge_store_associated_volumes(true);
    1042              :         }
    1043            0 :         return m_aaVolumeContainerEDGE[edge].end();
    1044              : }
    1045              : 
    1046            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_begin(Face* face)
    1047              : {
    1048            0 :         if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1049              :         {
    1050              :                 LOG("WARNING in associated_volumes_begin(face): auto-enabling FACEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1051            0 :                 face_store_associated_volumes(true);
    1052              :         }
    1053            0 :         return m_aaVolumeContainerFACE[face].begin();
    1054              : }
    1055              : 
    1056            0 : Grid::AssociatedVolumeIterator Grid::associated_volumes_end(Face* face)
    1057              : {
    1058            0 :         if(!option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES))
    1059              :         {
    1060              :                 LOG("WARNING in associated_volumes_end(face): auto-enabling FACEOPT_STORE_ASSOCIATED_VOLUMES." << endl);
    1061            0 :                 face_store_associated_volumes(true);
    1062              :         }
    1063            0 :         return m_aaVolumeContainerFACE[face].end();
    1064              : }
    1065              : 
    1066              : ////////////////////////////////////////////////////////////////////////
    1067              : ////////////////////////////////////////////////////////////////////////
    1068              : //      neighbourhood access
    1069            0 : Edge* Grid::get_edge(Vertex* v1, Vertex* v2)
    1070              : {
    1071            0 :         EdgeDescriptor ed(v1, v2);
    1072            0 :         return find_edge_in_associated_edges(v1, ed);
    1073              : }
    1074              : 
    1075            0 : Edge* Grid::get_edge(const EdgeVertices& ev)
    1076              : {
    1077            0 :         return find_edge_in_associated_edges(ev.vertex(0), ev);
    1078              : }
    1079              : 
    1080            0 : Edge* Grid::get_edge(Face* f, int ind)
    1081              : {
    1082              : //      check whether the face stores associated edges
    1083            0 :         if(option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES))
    1084              :         {
    1085            0 :                 if(option_is_enabled(FACEOPT_AUTOGENERATE_EDGES))
    1086            0 :                         return m_aaEdgeContainerFACE[f][ind];
    1087              :                 else{
    1088            0 :                         EdgeDescriptor ed;
    1089            0 :                         f->edge_desc(ind, ed);
    1090            0 :                         return find_edge_in_associated_edges(f, ed);
    1091              :                 }
    1092              :         }
    1093              :         else
    1094              :         {
    1095              :         //      get the descriptor of the i-th edge
    1096            0 :                 EdgeDescriptor ed;
    1097            0 :                 f->edge_desc(ind, ed);
    1098              :         //      it doesn't. find the edge by checking vertices.
    1099            0 :                 return find_edge_in_associated_edges(ed.vertex(0), ed);
    1100              :         }
    1101              :         
    1102              :         return NULL;
    1103              : }
    1104              : 
    1105            0 : Edge* Grid::get_edge(Volume* v, int ind)
    1106              : {
    1107              : //      check whether the face stores associated edges
    1108            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES))
    1109              :         {
    1110              :         //      if autogenerate is enabeld, edges are sorted.
    1111            0 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_EDGES)
    1112            0 :                         || option_is_enabled(VOLOPT_AUTOGENERATE_FACES
    1113              :                                                                 | FACEOPT_AUTOGENERATE_EDGES))
    1114              :                 {
    1115            0 :                         return m_aaEdgeContainerVOLUME[v][ind];
    1116              :                 }
    1117              :                 else{
    1118            0 :                         EdgeDescriptor ed;
    1119            0 :                         v->edge_desc(ind, ed);
    1120            0 :                         return find_edge_in_associated_edges(v, ed);
    1121              :                 }
    1122              :         }
    1123              :         else
    1124              :         {
    1125              :         //      get the descriptor of the i-th edge
    1126            0 :                 EdgeDescriptor ed;
    1127            0 :                 v->edge_desc(ind, ed);
    1128              :         //      it doesn't. find the edge by checking vertices.
    1129            0 :                 return find_edge_in_associated_edges(ed.vertex(0), ed);
    1130              :         }
    1131              :         
    1132              :         return NULL;
    1133              : }
    1134              : 
    1135            0 : Face* Grid::get_face(const FaceVertices& fv)
    1136              : {
    1137            0 :         return find_face_in_associated_faces(fv.vertex(0), fv);
    1138              : }
    1139              : 
    1140            0 : Face* Grid::get_face(Volume* v, int ind)
    1141              : {
    1142              : //      check whether the volume stores associated faces
    1143            0 :         if(option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES))
    1144              :         {
    1145              :         //      if autogenerate is enabeld, faces are sorted.
    1146            0 :                 if(option_is_enabled(VOLOPT_AUTOGENERATE_FACES))
    1147            0 :                         return m_aaFaceContainerVOLUME[v][ind];
    1148              :                 else{
    1149            0 :                         FaceDescriptor fd;
    1150            0 :                         v->face_desc(ind, fd);
    1151            0 :                         return find_face_in_associated_faces(v, fd);
    1152              :                 }
    1153              :         }
    1154              :         else {
    1155            0 :                 FaceDescriptor fd;
    1156            0 :                 v->face_desc(ind, fd);
    1157              :         //      it does not. check associated faces of the first vertex of fd.
    1158            0 :                 return find_face_in_associated_faces(fd.vertex(0), fd);
    1159              :         }
    1160              :         return NULL;
    1161              : }
    1162              : 
    1163            0 : Volume* Grid::get_volume(const VolumeVertices& vv)
    1164              : {
    1165            0 :         return find_volume_in_associated_volumes(vv.vertex(0), vv);
    1166              : }
    1167              : 
    1168              : ////////////////////////////////////////////////////////////////////////
    1169              : //      sides
    1170            0 : Vertex::side* Grid::get_side(Vertex* obj, size_t side)
    1171              : {
    1172              :         GRID_PROFILE_FUNC();
    1173              :         assert(!"ERROR in Grid::get_side(Vertex*, ...): A vertex doesn't have sides!");
    1174            0 :         return NULL;
    1175              : }
    1176              : 
    1177            0 : Edge::side* Grid::get_side(Edge* obj, size_t side)
    1178              : {
    1179              :         GRID_PROFILE_FUNC();
    1180              :         assert(side < 2 && "ERROR in Grid::get_side(Edge*, ...): Bad side index!");
    1181            0 :         return obj->vertex(side);
    1182              : }
    1183              : 
    1184            0 : Face::side* Grid::get_side(Face* obj, size_t side)
    1185              : {
    1186              :         GRID_PROFILE_FUNC();
    1187              :         assert(side < obj->num_edges() && "ERROR in Grid::get_side(Face*, ...): Bad side index!");
    1188            0 :         return get_edge(obj, side);
    1189              : }
    1190              : 
    1191            0 : Volume::side* Grid::get_side(Volume* obj, size_t side)
    1192              : {
    1193              :         GRID_PROFILE_FUNC();
    1194              :         assert(side < obj->num_faces() && "ERROR in Grid::get_side(Volume*, ...): Bad side index!");
    1195            0 :         return get_face(obj, side);
    1196              : }
    1197              : 
    1198              : ////////////////////////////////////////////////////////////////////////
    1199              : //      marks
    1200            0 : void Grid::init_marks()
    1201              : {
    1202              : //      attach marks to the elements
    1203            0 :         if(m_currentMark == 0)
    1204              :         {
    1205              :         //      marks have not yet been initialized - do that now
    1206              :         //      attach m_currentMark with default value 0
    1207              :         //      (0 is never the currentMark while marks are active).
    1208            0 :                 m_currentMark = 1;
    1209            0 :                 attach_to_vertices_dv(m_aMark, 0);
    1210            0 :                 attach_to_edges_dv(m_aMark, 0);
    1211            0 :                 attach_to_faces_dv(m_aMark, 0);
    1212            0 :                 attach_to_volumes_dv(m_aMark, 0);
    1213              :                 
    1214              :                 m_aaMarkVRT.access(*this, m_aMark);
    1215              :                 m_aaMarkEDGE.access(*this, m_aMark);
    1216              :                 m_aaMarkFACE.access(*this, m_aMark);
    1217              :                 m_aaMarkVOL.access(*this, m_aMark);
    1218              : 
    1219            0 :                 m_bMarking = false;
    1220              :         }
    1221            0 : }
    1222              : 
    1223            0 : void Grid::reset_marks()
    1224              : {
    1225              : //      set all marks to 0 and m_currentMark to 1
    1226            0 :         m_currentMark = 1;
    1227              :         AMark::ContainerType* pContainer;
    1228              : 
    1229              : //      reset vertex marks
    1230            0 :         pContainer = get_attachment_data_container<Vertex>(m_aMark);
    1231            0 :         for(uint i = 0; i < pContainer->size(); ++i)
    1232            0 :                 pContainer->get_elem(i) = 0;
    1233              : 
    1234              : //      reset edge marks
    1235              :         pContainer = get_attachment_data_container<Edge>(m_aMark);
    1236            0 :         for(uint i = 0; i < pContainer->size(); ++i)
    1237            0 :                 pContainer->get_elem(i) = 0;
    1238              : 
    1239              : //      reset face marks
    1240              :         pContainer = get_attachment_data_container<Face>(m_aMark);
    1241            0 :         for(uint i = 0; i < pContainer->size(); ++i)
    1242            0 :                 pContainer->get_elem(i) = 0;
    1243              : 
    1244              : //      reset volume marks
    1245              :         pContainer = get_attachment_data_container<Volume>(m_aMark);
    1246            0 :         for(uint i = 0; i < pContainer->size(); ++i)
    1247            0 :                 pContainer->get_elem(i) = 0; 
    1248            0 : }
    1249              : 
    1250            1 : void Grid::remove_marks()
    1251              : {
    1252            1 :         if(m_currentMark != 0)
    1253              :         {
    1254            0 :                 m_currentMark = 0;
    1255            0 :                 detach_from_vertices(m_aMark);
    1256              :                 detach_from_edges(m_aMark);
    1257              :                 detach_from_faces(m_aMark);
    1258              :                 detach_from_volumes(m_aMark);
    1259              :         }
    1260            1 : }
    1261              : 
    1262            0 : void Grid::begin_marking()
    1263              : {
    1264            0 :         if(m_currentMark == 0)
    1265              :         {
    1266              :         //      marks are disabled. we have to activate them
    1267            0 :                 init_marks();
    1268              :         }
    1269              :         
    1270            0 :         if(m_bMarking){
    1271            0 :                 throw(UGError("ERROR in Grid::begin_marking(): marking is already active. Don't forget to call end_marking when you're done with marking."));
    1272              :         }
    1273              :         
    1274              : //      increase currentMark
    1275            0 :         ++m_currentMark;
    1276              :         
    1277              : //      check whether we have to reset-marks
    1278            0 :         if(m_currentMark == -1)
    1279            0 :                 reset_marks();
    1280              :                 
    1281              : //      set m_bMarking to true
    1282            0 :         m_bMarking = true;
    1283            0 : }
    1284              : 
    1285            0 : void Grid::end_marking()
    1286              : {
    1287            0 :         m_bMarking = false;
    1288            0 : }
    1289              : 
    1290            0 : void Grid::clear_marks()
    1291              : {
    1292            0 :         if(m_bMarking){
    1293            0 :                 end_marking();
    1294            0 :                 begin_marking();
    1295              :         }
    1296              :         else{
    1297            0 :                 begin_marking();
    1298            0 :                 end_marking();
    1299              :         }
    1300            0 : }
    1301              : 
    1302            0 : void Grid::test_attached_linked_lists()
    1303              : {
    1304              :         UG_LOG("empty\n");
    1305            0 : }
    1306              : 
    1307              : }//     end of namespace
        

Generated by: LCOV version 2.0-1