ug4
dual_graph.h
Go to the documentation of this file.
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 #ifndef __H__LIB_GRID__DUAL_GRAPH__
34 #define __H__LIB_GRID__DUAL_GRAPH__
35 
36 #include <vector>
37 #include "lib_grid/lg_base.h"
38 
39 namespace ug
40 {
41 
43 
79 template <class TGeomBaseObj, class TIndexType>
80 void ConstructDualGraph(std::vector<TIndexType>& adjacencyMapStructureOut,
81  std::vector<TIndexType>& adjacencyMapOut,
82  Grid& grid, Attachment<TIndexType>* paIndex = NULL,
83  TGeomBaseObj** pGeomObjsOut = NULL,
84  NeighborhoodType nbhType = NHT_DEFAULT,
85  const GridObjectCollection* pgoc = NULL)
86 {
87  using namespace std;
88  typedef TGeomBaseObj Elem;
89  typedef typename geometry_traits<Elem>::iterator ElemIterator;
90 
91 // set up index attachment and attachment accessor
92  typedef Attachment<TIndexType> AIndex;
93  AIndex aIndex;
94  if(paIndex)
95  aIndex = *paIndex;
96 
97  if(!grid.has_attachment<Elem>(aIndex))
98  grid.attach_to_dv<Elem>(aIndex, -1);
99 
100  Grid::AttachmentAccessor<Elem, AIndex> aaInd(grid, aIndex);
101 
103  if(pgoc)
104  goc = *pgoc;
105  else
106  goc = grid.get_grid_objects();
107 
108 // init the indices
109  TIndexType ind = 0;
110  for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
111  {
112  for(ElemIterator iter = goc.begin<Elem>(lvl); iter != goc.end<Elem>(lvl);
113  ++iter, ++ind)
114  {
115  aaInd[*iter] = ind;
116  }
117  }
118 
119 // init the adjacencyMapStructure
120  adjacencyMapStructureOut.resize(goc.num<Elem>() + 1);
121  adjacencyMapOut.clear();
122 
123 // construct the graph
124  {
125  vector<Elem*> vNeighbours;
126  int ind = 0;
127 
128  // iterate through all elements
129  for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
130  {
131  for(ElemIterator iter = goc.begin<Elem>(lvl);
132  iter != goc.end<Elem>(lvl); ++iter, ++ind)
133  {
134  // get all neighbours
135  CollectNeighbors(vNeighbours, *iter, grid, nbhType);
136 
137  // store first entry at which the connections will be written to the map
138  adjacencyMapStructureOut[ind] = adjacencyMapOut.size();
139 
140  // iterate over the neighbours and push adjacent indices to the adjacencyMap
141  for(size_t i = 0; i < vNeighbours.size(); ++i)
142  adjacencyMapOut.push_back(aaInd[vNeighbours[i]]);
143  }
144  }
145  }
146 
147 // add the final element
148  adjacencyMapStructureOut[adjacencyMapStructureOut.size() - 1] = adjacencyMapOut.size();
149 
150 // fill pGeomObjsOut
151  if(pGeomObjsOut)
152  {
153  int ind = 0;
154  for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
155  for(ElemIterator iter = goc.begin<Elem>(lvl);
156  iter != goc.end<Elem>(lvl); ++iter, ++ind)
157  {
158  pGeomObjsOut[ind] = *iter;
159  }
160  }
161  }
162 
163 // clean up
164  if(!paIndex)
165  grid.detach_from<Elem>(aIndex);
166 }
167 
168 
170 
207 template <class TGeomBaseObj, class TIndexType>
208 void ConstructDualGraphMG(std::vector<TIndexType>& adjacencyMapStructureOut,
209  std::vector<TIndexType>& adjacencyMapOut,
210  std::vector<TIndexType>* pEdgeWeightsOut,
211  MultiGrid& mg, size_t baseLevel = 0,
212  int hWeight = 1, int vWeight = 1,
213  Attachment<TIndexType>* paIndex = NULL,
214  TGeomBaseObj** pGeomObjsOut = NULL,
215  NeighborhoodType nbhType = NHT_DEFAULT)
216 {
217  using namespace std;
218  typedef TGeomBaseObj Elem;
219  typedef typename geometry_traits<Elem>::iterator ElemIterator;
220 
221 // set up index attachment and attachment accessor
222  typedef Attachment<TIndexType> AIndex;
223  AIndex aIndex;
224  if(paIndex)
225  aIndex = *paIndex;
226 
227  if(!mg.has_attachment<Elem>(aIndex))
228  mg.attach_to<Elem>(aIndex);
229 
230  Grid::AttachmentAccessor<Elem, AIndex> aaInd(mg, aIndex);
231 
232 // init the indices
233  TIndexType ind = 0;
234  size_t numElems = 0;
235  for(size_t lvl = baseLevel; lvl < mg.num_levels(); ++lvl)
236  {
237  numElems += mg.num<Elem>(lvl);
238  for(ElemIterator iter = mg.begin<Elem>(lvl); iter != mg.end<Elem>(lvl);
239  ++iter, ++ind)
240  {
241  aaInd[*iter] = ind;
242  }
243  }
244 
245 // init the adjacencyMapStructure
246  adjacencyMapStructureOut.resize(numElems + 1);
247  adjacencyMapOut.clear();
248  if(pEdgeWeightsOut)
249  pEdgeWeightsOut->clear();
250 
251 // construct the graph
252  {
253  vector<Elem*> vNeighbours;
254  int ind = 0;
255 
256  // iterate through all elements
257  for(size_t lvl = baseLevel; lvl < mg.num_levels(); ++lvl)
258  {
259  for(ElemIterator iter = mg.begin<Elem>(lvl);
260  iter != mg.end<Elem>(lvl); ++iter, ++ind)
261  {
262  Elem* elem = *iter;
263 
264  // get all neighbours
265  CollectNeighbors(vNeighbours, elem, mg, nbhType);
266 
267  // store first entry at which the connections will be written to the map
268  adjacencyMapStructureOut[ind] = adjacencyMapOut.size();
269 
270  // iterate over the neighbours and push adjacent indices to the adjacencyMap
271  for(size_t i = 0; i < vNeighbours.size(); ++i)
272  adjacencyMapOut.push_back(aaInd[vNeighbours[i]]);
273 
274  if(pEdgeWeightsOut){
275  for(size_t i = 0; i < vNeighbours.size(); ++i)
276  pEdgeWeightsOut->push_back(hWeight);
277  }
278 
279  // add a connection to the parents to the list
280  GridObject* parent = mg.get_parent(elem);
281  if(parent && Elem::type_match(parent)){
282  adjacencyMapOut.push_back(aaInd[static_cast<Elem*>(parent)]);
283  if(pEdgeWeightsOut)
284  pEdgeWeightsOut->push_back(vWeight);
285  }
286 
287  // add children to the list
288  //todo: add edge-weights
289  size_t numChildren = mg.num_children<Elem>(elem);
290  for(size_t i = 0; i < numChildren; ++i){
291  adjacencyMapOut.push_back(aaInd[mg.get_child<Elem>(elem, i)]);
292  }
293 
294  if(pEdgeWeightsOut){
295  for(size_t i = 0; i < numChildren; ++i)
296  pEdgeWeightsOut->push_back(1);
297  }
298  }
299  }
300  }
301 
302 // add the final element
303  adjacencyMapStructureOut[adjacencyMapStructureOut.size() - 1] = adjacencyMapOut.size();
304 
305 // fill pGeomObjsOut
306  if(pGeomObjsOut)
307  {
308  int ind = 0;
309  for(size_t lvl = baseLevel; lvl < mg.num_levels(); ++lvl){
310  for(ElemIterator iter = mg.begin<Elem>(lvl);
311  iter != mg.end<Elem>(lvl); ++iter, ++ind)
312  {
313  pGeomObjsOut[ind] = *iter;
314  }
315  }
316  }
317 
318 // clean up
319  if(!paIndex)
320  mg.detach_from<Elem>(aIndex);
321 }
322 
323 
324 template <typename TBaseElem>
326 {
327  public:
329  virtual void collect_neighbors(std::vector<TBaseElem*>& neighborsOut, TBaseElem* elem) = 0;
330 };
331 
333 
369 template <class TGeomBaseObj, class TIndexType>
371  std::vector<TIndexType>& adjacencyMapStructureOut,
372  std::vector<TIndexType>& adjacencyMapOut,
373  MultiGrid& mg, size_t level,
374  Attachment<TIndexType>* paIndex = NULL,
375  TGeomBaseObj** pGeomObjsOut = NULL,
376  NeighborhoodType nbhType = NHT_DEFAULT,
377  DualGraphNeighborCollector<TGeomBaseObj>* neighborCollector = NULL)
378 {
379  using namespace std;
380  typedef TGeomBaseObj Elem;
381  typedef typename geometry_traits<Elem>::iterator ElemIterator;
382 
383 // set up index attachment and attachment accessor
384  typedef Attachment<TIndexType> AIndex;
385  AIndex aIndex;
386  if(paIndex)
387  aIndex = *paIndex;
388 
389  if(!mg.has_attachment<Elem>(aIndex))
390  mg.attach_to<Elem>(aIndex);
391 
392  Grid::AttachmentAccessor<Elem, AIndex> aaInd(mg, aIndex);
393 
394 // init the indices
395  size_t numElems = mg.num<Elem>(level);
396  {
397  TIndexType ind = 0;
398  for(ElemIterator iter = mg.begin<Elem>(level); iter != mg.end<Elem>(level);
399  ++iter, ++ind)
400  {
401  aaInd[*iter] = ind;
402  }
403  }
404 
405 // init the adjacencyMapStructure
406  adjacencyMapStructureOut.resize(numElems + 1);
407  adjacencyMapOut.clear();
408 
409 // construct the graph
410  vector<Elem*> vNeighbours;
411  int ind = 0;
412 
413 // generate adjacency structure first
414  for(ElemIterator iter = mg.begin<Elem>(level);
415  iter != mg.end<Elem>(level); ++iter, ++ind)
416  {
417  Elem* elem = *iter;
418 
419  // get all neighbours
420  if (neighborCollector)
421  neighborCollector->collect_neighbors(vNeighbours, elem);
422  else
423  CollectNeighbors(vNeighbours, elem, mg, nbhType);
424 
425  // store first entry at which the connections will be written to the map
426  adjacencyMapStructureOut[ind] = adjacencyMapOut.size();
427 
428  // iterate over the neighbours and push adjacent indices to the adjacencyMap
429  for(size_t i = 0; i < vNeighbours.size(); ++i)
430  adjacencyMapOut.push_back(aaInd[vNeighbours[i]]);
431  }
432 
433 // add the final element
434  adjacencyMapStructureOut[adjacencyMapStructureOut.size() - 1] = adjacencyMapOut.size();
435 
436 // fill pGeomObjsOut
437  if(pGeomObjsOut)
438  {
439  int ind = 0;
440  for(ElemIterator iter = mg.begin<Elem>(level);
441  iter != mg.end<Elem>(level); ++iter, ++ind)
442  {
443  pGeomObjsOut[ind] = *iter;
444  }
445  }
446 
447 // clean up
448  if(!paIndex)
449  mg.detach_from<Elem>(aIndex);
450 }
451 
452 
453 }// end of namespace
454 
455 #endif
A generic specialization of IAttachment.
Definition: attachment_pipe.h:263
Definition: dual_graph.h:326
virtual void collect_neighbors(std::vector< TBaseElem * > &neighborsOut, TBaseElem *elem)=0
virtual ~DualGraphNeighborCollector()
Definition: dual_graph.h:328
the generic attachment-accessor for access to grids attachment pipes.
Definition: grid.h:182
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
void detach_from(IAttachment &attachment)
Definition: grid_impl.hpp:369
void attach_to(IAttachment &attachment, bool passOnValues)
attach with custom pass-on-behaviour and unspecified default value.
Definition: grid_impl.hpp:296
bool has_attachment(IAttachment &attachment)
Definition: grid.h:796
virtual GridObjectCollection get_grid_objects()
returns the the GridObjectCollection of the grid:
Definition: grid.cpp:527
void attach_to_dv(TAttachment &attachment, const typename TAttachment::ValueType &defaultValue)
Definition: grid_impl.hpp:326
a helper class that holds a collection of possibly unconnected geometric-objects.
Definition: grid_object_collection.h:96
geometry_traits< TGeomObj >::iterator begin(size_t level=0)
Definition: grid_object_collection_impl.hpp:95
geometry_traits< TGeomObj >::iterator end(size_t level=0)
Definition: grid_object_collection_impl.hpp:106
size_t num() const
Definition: grid_object_collection_impl.hpp:130
size_t num_levels() const
returns the number of levels
Definition: grid_object_collection.h:128
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
Definition: multi_grid.h:72
size_t num_levels() const
number of levels
Definition: multi_grid.h:145
TChild * get_child(TElem *elem, size_t ind) const
returns the i-th child of the given child-type
Definition: multi_grid.h:268
size_t num(int level) const
Definition: multi_grid.h:154
GridObject * get_parent(GridObject *parent) const
Definition: multi_grid.cpp:180
geometry_traits< TElem >::iterator end(int level)
Definition: multi_grid.h:168
geometry_traits< TElem >::iterator begin(int level)
Definition: multi_grid.h:158
size_t num_children(TElem *elem) const
returns the number of children of the given child-type
Definition: multi_grid.h:225
Definition: grid_base_object_traits.h:68
NeighborhoodType
Constants to specify a neighborhood.
Definition: neighborhood.h:53
void CollectNeighbors(std::vector< Vertex * > &vNeighborsOut, Grid &grid, Vertex *vrt, uint nbhType, Grid::edge_traits::callback considerEdge, Grid::face_traits::callback considerFace, Grid::volume_traits::callback considerVol)
Collects all vertices that are connected by elements of the specified type.
Definition: neighborhood.cpp:43
@ NHT_DEFAULT
Definition: neighborhood.h:54
base_type::TBaseElem TBaseElem
Definition: smart_pointer.h:814
the ug namespace
void ConstructDualGraph(std::vector< TIndexType > &adjacencyMapStructureOut, std::vector< TIndexType > &adjacencyMapOut, Grid &grid, Attachment< TIndexType > *paIndex=NULL, TGeomBaseObj **pGeomObjsOut=NULL, NeighborhoodType nbhType=NHT_DEFAULT, const GridObjectCollection *pgoc=NULL)
Definition: dual_graph.h:80
void ConstructDualGraphMG(std::vector< TIndexType > &adjacencyMapStructureOut, std::vector< TIndexType > &adjacencyMapOut, std::vector< TIndexType > *pEdgeWeightsOut, MultiGrid &mg, size_t baseLevel=0, int hWeight=1, int vWeight=1, Attachment< TIndexType > *paIndex=NULL, TGeomBaseObj **pGeomObjsOut=NULL, NeighborhoodType nbhType=NHT_DEFAULT)
Definition: dual_graph.h:208
void ConstructDualGraphMGLevel(std::vector< TIndexType > &adjacencyMapStructureOut, std::vector< TIndexType > &adjacencyMapOut, MultiGrid &mg, size_t level, Attachment< TIndexType > *paIndex=NULL, TGeomBaseObj **pGeomObjsOut=NULL, NeighborhoodType nbhType=NHT_DEFAULT, DualGraphNeighborCollector< TGeomBaseObj > *neighborCollector=NULL)
Definition: dual_graph.h:370