LCOV - code coverage report
Current view: top level - ugbase/lib_grid/grid - neighborhood.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 152 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-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 "neighborhood.h"
      34              : #include "lib_grid/algorithms/geom_obj_util/vertex_util.h"
      35              : 
      36              : using namespace std;
      37              : 
      38              : namespace ug
      39              : {
      40              :                                                         
      41              : ////////////////////////////////////////////////////////////////////////
      42              : //
      43            0 : void CollectNeighbors(std::vector<Vertex*>& vNeighborsOut,
      44              :                                                 Grid& grid, Vertex* vrt, uint nbhType,
      45              :                                                 Grid::edge_traits::callback considerEdge,
      46              :                                                 Grid::face_traits::callback considerFace,
      47              :                                                 Grid::volume_traits::callback considerVol)
      48              : {
      49              : //      clear the container
      50              :         vNeighborsOut.clear();
      51              :         
      52              : //      begin marking
      53            0 :         grid.begin_marking();
      54              :         
      55              : //      mark vrt - this makes things easier
      56              :         grid.mark(vrt);
      57              :         
      58              : //      iterate through associated edges
      59            0 :         if(nbhType & NHT_EDGE_NEIGHBORS){
      60            0 :                 Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(vrt);
      61            0 :                 for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(vrt);
      62            0 :                         iter != iterEnd; ++iter)
      63              :                 {
      64            0 :                         if(considerEdge(*iter)){
      65            0 :                                 Vertex* neighbour = GetConnectedVertex(*iter, vrt);
      66            0 :                                 if(!grid.is_marked(neighbour)){
      67              :                                         grid.mark(neighbour);
      68            0 :                                         vNeighborsOut.push_back(neighbour);
      69              :                                 }
      70              :                         }
      71              :                 }
      72              :         }
      73              : 
      74              : //      iterate through associated faces
      75            0 :         if(nbhType & NHT_FACE_NEIGHBORS){
      76            0 :                 Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrt);
      77            0 :                 for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrt);
      78            0 :                         iter != iterEnd; ++iter)
      79              :                 {
      80            0 :                         if(considerFace(*iter)){
      81            0 :                                 Face* f = *iter;
      82            0 :                                 size_t numVrts = f->num_vertices();
      83            0 :                                 Face::ConstVertexArray vrts = f->vertices();
      84            0 :                                 for(size_t i = 0; i < numVrts; ++i){
      85            0 :                                         Vertex* neighbour = vrts[i];
      86            0 :                                         if(!grid.is_marked(neighbour)){
      87              :                                                 grid.mark(neighbour);
      88            0 :                                                 vNeighborsOut.push_back(neighbour);
      89              :                                         }
      90              :                                 }
      91              :                         }
      92              :                 }
      93              :         }
      94              : 
      95              : //      iterate through associated volumes
      96            0 :         if(nbhType & NHT_VOLUME_NEIGHBORS){
      97            0 :                 Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrt);
      98            0 :                 for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrt);
      99            0 :                         iter != iterEnd; ++iter)
     100              :                 {
     101            0 :                         if(considerVol(*iter)){
     102            0 :                                 Volume* v = *iter;
     103            0 :                                 size_t numVrts = v->num_vertices();
     104            0 :                                 Volume::ConstVertexArray vrts = v->vertices();
     105            0 :                                 for(size_t i = 0; i < numVrts; ++i){
     106            0 :                                         Vertex* neighbour = vrts[i];
     107            0 :                                         if(!grid.is_marked(neighbour)){
     108              :                                                 grid.mark(neighbour);
     109            0 :                                                 vNeighborsOut.push_back(neighbour);
     110              :                                         }
     111              :                                 }
     112              :                         }
     113              :                 }
     114              :         }
     115              :                 
     116              : //      end marking
     117            0 :         grid.end_marking();
     118            0 : }
     119              :                                                         
     120              : ////////////////////////////////////////////////////////////////////////
     121              : //      CollectNeighbors
     122            0 : void CollectNeighbors(std::vector<Edge*>& vNeighborsOut, Edge* e,
     123              :                                            Grid& grid, NeighborhoodType nbhType)
     124              : {
     125              : //      clear the container
     126              :         vNeighborsOut.clear();
     127              :         
     128              : //      default neighbourhood:
     129            0 :         if(nbhType == NHT_DEFAULT)
     130              :                 nbhType = NHT_VERTEX_NEIGHBORS;
     131              : 
     132              : //      edges can only be vertex-neighbours
     133            0 :         if(nbhType != NHT_VERTEX_NEIGHBORS)
     134              :                 return;
     135              : 
     136              : //      begin marking
     137            0 :         grid.begin_marking();
     138              :         
     139              : //      mark the edge
     140              :         grid.mark(e);
     141              :         
     142              : //      mark the vertices of the edge
     143            0 :         grid.mark(e->vertex(0));
     144            0 :         grid.mark(e->vertex(1));     
     145              :         
     146              : //      iterate over all edges that are connected to the vertices.
     147              : //      if the edge is not yet marked, we have to push it to vNeighboursOut.
     148            0 :         for(uint i = 0; i < 2; ++i)
     149              :         {
     150            0 :                 Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(e->vertex(i));
     151            0 :                 for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(e->vertex(i));
     152            0 :                         iter != iterEnd; ++iter)
     153              :                 {
     154            0 :                         if(!grid.is_marked(*iter))
     155              :                         {
     156            0 :                                 vNeighborsOut.push_back(*iter);
     157            0 :                                 grid.mark(*iter);
     158              :                         }
     159              :                 }
     160              :         }
     161              : 
     162              : //      end marking
     163            0 :         grid.end_marking();
     164              : }
     165              : 
     166              : 
     167              : ////////////////////////////////////////////////////////////////////////
     168              : //      CollectNeighbors
     169            0 : void CollectNeighbors(std::vector<Face*>& vNeighborsOut, Face* f,
     170              :                                            Grid& grid, NeighborhoodType nbhType)
     171              : {
     172              : //      clear the container
     173              :         vNeighborsOut.clear();
     174              :         
     175              : //      default neighbourhood:
     176            0 :         if(nbhType == NHT_DEFAULT)
     177              :                 nbhType = NHT_EDGE_NEIGHBORS;
     178              : 
     179              : //      faces can't be face-neighbours
     180            0 :         if(nbhType == NHT_FACE_NEIGHBORS)
     181              :                 return;
     182              : 
     183              : //      begin marking
     184            0 :         grid.begin_marking();
     185              :         
     186              : //      mark the face
     187              :         grid.mark(f);
     188              :         
     189              : //      mark the vertices of the face
     190            0 :         uint numVrts = f->num_vertices();
     191            0 :         Face::ConstVertexArray vrts = f->vertices();
     192            0 :         for(uint i = 0; i < numVrts; ++i)
     193            0 :                 grid.mark(vrts[i]);
     194              :         
     195              : //      in order to get the maximum speed-up, we'll try to use
     196              : //      associated elements in grid.
     197              :         if((nbhType == NHT_EDGE_NEIGHBORS)
     198            0 :                 && grid.option_is_enabled(FACEOPT_STORE_ASSOCIATED_EDGES
     199              :                                                                   | EDGEOPT_STORE_ASSOCIATED_FACES
     200              :                                                                   | FACEOPT_AUTOGENERATE_EDGES))
     201              :         {
     202              :         //      iterate through associated edges
     203            0 :                 Grid::AssociatedEdgeIterator eEnd = grid.associated_edges_end(f);
     204            0 :                 for(Grid::AssociatedEdgeIterator eIter = grid.associated_edges_begin(f);
     205            0 :                         eIter != eEnd; ++eIter)
     206              :                 {
     207              :                 //      iterate through associated folumes of the eace
     208            0 :                         Grid::AssociatedFaceIterator fEnd = grid.associated_faces_end(*eIter);
     209            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(*eIter);
     210            0 :                                 iter != fEnd; ++iter)
     211              :                         {
     212              :                         //      if the face is not yet marked, then add it to the neighbours
     213            0 :                                 if(!grid.is_marked(*iter))
     214              :                                 {
     215              :                                         grid.mark(*iter);
     216            0 :                                         vNeighborsOut.push_back(*iter);
     217              :                                 }
     218              :                         }
     219              :                 }
     220              :         //      we're done in here. end-marking and return.
     221            0 :                 grid.end_marking();
     222              :                 return;
     223              :         }
     224              : 
     225              : 
     226              : //      iterate over all faces that are connected to the vertices.
     227              : //      if the face shares the elements as required by nbhType and
     228              : //      it is not yet marked, we have to push it to vNeighboursOut.
     229              : //      to optimize speed we'll check both valid nbhTypes separately.
     230              : //      the first case indeed is a subcase of the second
     231              : //      (compare counted marked vertices against nbhType)
     232            0 :         switch(nbhType)
     233              :         {
     234              :         case NHT_VERTEX_NEIGHBORS:
     235            0 :                 for(uint i = 0; i < numVrts; ++i)
     236              :                 {
     237            0 :                         Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrts[i]);
     238            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrts[i]);
     239            0 :                                 iter != iterEnd; ++iter)
     240              :                         {
     241            0 :                                 if(!grid.is_marked(*iter))
     242              :                                 {
     243            0 :                                         vNeighborsOut.push_back(*iter);
     244            0 :                                         grid.mark(*iter);
     245              :                                 }
     246              :                         }
     247              :                 }
     248              :                 break;
     249              : 
     250              :         case NHT_EDGE_NEIGHBORS:
     251            0 :                 for(uint i = 0; i < numVrts; ++i)
     252              :                 {
     253            0 :                         Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(vrts[i]);
     254            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(vrts[i]);
     255            0 :                                 iter != iterEnd; ++iter)
     256              :                         {
     257            0 :                                 Face* nf = *iter;
     258            0 :                                 if(!grid.is_marked(nf))
     259              :                                 {
     260              :                                 //      count the marked vertices that are contained by *iter
     261              :                                 //      if there are more than 1, the faces share an edge
     262              :                                 //      (at least in a regular grid)
     263              :                                         int counter = 0;
     264              :                                         
     265            0 :                                         size_t numNVrts = nf->num_vertices();
     266            0 :                                         Face::ConstVertexArray nvrts = nf->vertices();
     267              : 
     268            0 :                                         for(uint j = 0; j < numNVrts; ++j)
     269              :                                         {
     270            0 :                                                 if(grid.is_marked(nvrts[j]))
     271              :                                                 {
     272            0 :                                                         ++counter;
     273            0 :                                                         if(counter > 1)
     274              :                                                         {
     275            0 :                                                                 vNeighborsOut.push_back(nf);
     276              :                                                                 grid.mark(nf);
     277              :                                                                 break;
     278              :                                                         }
     279              :                                                 }
     280              :                                         }
     281              :                                 }
     282              :                         }
     283              :                 }
     284              :                 break;
     285              :         default:
     286              :                 break;
     287              :         }
     288              : 
     289              : //      end marking
     290            0 :         grid.end_marking();
     291              : }
     292              : 
     293              : ////////////////////////////////////////////////////////////////////////
     294              : //      CollectNeighbors
     295            0 : void CollectNeighbors(std::vector<Volume*>& vNeighborsOut, Volume* v,
     296              :                                            Grid& grid, NeighborhoodType nbhType)
     297              : {
     298              : //      clear the container
     299              :         vNeighborsOut.clear();
     300              :         
     301              : //      default neighbourhood:
     302            0 :         if(nbhType == NHT_DEFAULT)
     303              :                 nbhType = NHT_FACE_NEIGHBORS;
     304              : 
     305              : //      begin marking
     306            0 :         grid.begin_marking();
     307              :         
     308              : //      mark the volume
     309              :         grid.mark(v);
     310              :         
     311              : //      mark the vertices of the volume
     312            0 :         uint numVrts = v->num_vertices();
     313            0 :         Volume::ConstVertexArray vrts = v->vertices();
     314            0 :         for(uint i = 0; i < numVrts; ++i)
     315            0 :                 grid.mark(vrts[i]);
     316              : 
     317              : //      in order to get the maximum speed-up, we'll try to use
     318              : //      associated elements in grid.
     319              :         if((nbhType == NHT_FACE_NEIGHBORS)
     320            0 :                 && grid.option_is_enabled(VOLOPT_STORE_ASSOCIATED_FACES
     321              :                                                                   | FACEOPT_STORE_ASSOCIATED_VOLUMES
     322              :                                                                   | VOLOPT_AUTOGENERATE_FACES))
     323              :         {
     324              :         //      iterate through associated faces
     325            0 :                 Grid::AssociatedFaceIterator fEnd = grid.associated_faces_end(v);
     326            0 :                 for(Grid::AssociatedFaceIterator fIter = grid.associated_faces_begin(v);
     327            0 :                         fIter != fEnd; ++fIter)
     328              :                 {
     329              :                 //      iterate through associated volumes of the face
     330            0 :                         Grid::AssociatedVolumeIterator vEnd = grid.associated_volumes_end(*fIter);
     331            0 :                         for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(*fIter);
     332            0 :                                 iter != vEnd; ++iter)
     333              :                         {
     334              :                         //      if the volume is not yet marked, then add it to the neighbours
     335            0 :                                 if(!grid.is_marked(*iter))
     336              :                                 {
     337              :                                         grid.mark(*iter);
     338            0 :                                         vNeighborsOut.push_back(*iter);
     339              :                                 }
     340              :                         }
     341              :                 }
     342              :         //      we're done in here. end-marking and return.
     343            0 :                 grid.end_marking();
     344              :                 return;
     345              :         }
     346              : 
     347              : //      iterate over all volumes that are connected to the vertices.
     348              : //      if the volume shares the elements as required by nbhType and
     349              : //      it is not yet marked, we have to push it to vNeighboursOut.
     350              : //      to optimize speed we'll check both valid nbhTypes separately.
     351              : //      the first case indeed is a subcase of the second
     352            0 :         if(nbhType & NHT_VERTEX_NEIGHBORS)
     353            0 :                 for(uint i = 0; i < numVrts; ++i)
     354              :                 {
     355            0 :                         Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrts[i]);
     356            0 :                         for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrts[i]);
     357            0 :                                 iter != iterEnd; ++iter)
     358              :                         {
     359            0 :                                 if(!grid.is_marked(*iter))
     360              :                                 {
     361            0 :                                         vNeighborsOut.push_back(*iter);
     362            0 :                                         grid.mark(*iter);
     363              :                                 }
     364              :                         }
     365              :                 }
     366              :         else
     367              :         {
     368              :         //      count the number of shared vertices with volumes, which are connected by
     369              :         //      at least one vertex. This case handles both face and edge neighborhoods.
     370              :                 int minNumSharedVrts = -1;
     371            0 :                 if(nbhType & NHT_FACE_NEIGHBORS)
     372              :                         minNumSharedVrts = 3;
     373            0 :                 if(nbhType & NHT_EDGE_NEIGHBORS)
     374              :                         minNumSharedVrts = 2;
     375              : 
     376            0 :                 if(minNumSharedVrts > 0){
     377            0 :                         for(uint i = 0; i < numVrts; ++i)
     378              :                         {
     379            0 :                                 Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrts[i]);
     380            0 :                                 for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrts[i]);
     381            0 :                                         iter != iterEnd; ++iter)
     382              :                                 {
     383            0 :                                         Volume* nv = *iter;
     384            0 :                                         if(!grid.is_marked(nv))
     385              :                                         {
     386              :                                         //      count the marked vertices that are contained by *iter
     387              :                                         //      if there as many as in nbhTypes, the volume is a neighbour.
     388              :                                         //      (at least in a regular grid)
     389              :                                                 int counter = 0;
     390            0 :                                                 size_t numNVrts = nv->num_vertices();
     391            0 :                                                 Volume::ConstVertexArray nvrts = nv->vertices();
     392            0 :                                                 for(uint j = 0; j < numNVrts; ++j)
     393              :                                                 {
     394            0 :                                                         if(grid.is_marked(nvrts[j]))
     395              :                                                         {
     396            0 :                                                                 ++counter;
     397            0 :                                                                 if(counter >= minNumSharedVrts)
     398              :                                                                 {
     399            0 :                                                                         vNeighborsOut.push_back(nv);
     400              :                                                                         grid.mark(nv);
     401              :                                                                         break;
     402              :                                                                 }
     403              :                                                         }
     404              :                                                 }
     405              :                                         }
     406              :                                 }
     407              :                         }
     408              :                 }
     409              :         }
     410              : 
     411              : //      end marking
     412            0 :         grid.end_marking();
     413              : }
     414              : 
     415            0 : void CollectNeighborhood(std::vector<Face*>& facesOut, Grid& grid,
     416              :                                                   Vertex* vrt, size_t range,
     417              :                                                   bool clearContainer)
     418              : {
     419            0 :         if(clearContainer)
     420              :                 facesOut.clear();
     421              :         
     422              :         vector<Vertex*> candidates;
     423              :         size_t rangeBegin = 0;
     424              :         size_t rangeEnd = 1;
     425              :         
     426            0 :         candidates.push_back(vrt);
     427              :         
     428            0 :         grid.begin_marking();
     429            0 :         grid.mark(vrt);
     430              :         
     431              : //      we iterate over the range
     432            0 :         for(size_t i_range = 0; i_range < range; ++i_range){
     433              :         //      iterate from candidatesStart to candidatesEnd
     434              :         //      this is important, since we can make sure that only triangles
     435              :         //      in the correct range are considered
     436            0 :                 for(size_t i_vrt = rangeBegin; i_vrt < rangeEnd; ++i_vrt)
     437              :                 {
     438            0 :                         Vertex* v = candidates[i_vrt];
     439              :                 //      iterate over associated faces
     440            0 :                         for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v);
     441            0 :                                 iter != grid.associated_faces_end(v); ++iter)
     442              :                         {
     443            0 :                                 Face* f = *iter;
     444            0 :                                 if(!grid.is_marked(f)){
     445              :                                         grid.mark(f);
     446            0 :                                         facesOut.push_back(f);
     447            0 :                                         size_t numVrts = f->num_vertices();
     448            0 :                                         Face::ConstVertexArray vrts = f->vertices();
     449            0 :                                         for(size_t i = 0; i < numVrts; ++i){
     450            0 :                                                 if(!grid.is_marked(vrts[i])){
     451              :                                                         grid.mark(vrts[i]);
     452            0 :                                                         candidates.push_back(vrts[i]);
     453              :                                                 }
     454              :                                         }
     455              :                                 }
     456              :                         }
     457              :                 }
     458              :                 
     459              :         //      prepare next iteration
     460              :                 rangeBegin = rangeEnd;
     461              :                 rangeEnd = candidates.size();
     462              :         }
     463              :         
     464            0 :         grid.end_marking();
     465            0 : }
     466              : 
     467              : }//     end of namespace
        

Generated by: LCOV version 2.0-1