Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
39namespace ug
40{
41
43
79template <class TGeomBaseObj, class TIndexType>
80void ConstructDualGraph(std::vector<TIndexType>& adjacencyMapStructureOut,
81 std::vector<TIndexType>& adjacencyMapOut,
82 Grid& grid, Attachment<TIndexType>* paIndex = NULL,
83 TGeomBaseObj** pGeomObjsOut = NULL,
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
207template <class TGeomBaseObj, class TIndexType>
208void 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,
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
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
324template <typename TBaseElem>
326{
327 public:
329 virtual void collect_neighbors(std::vector<TBaseElem*>& neighborsOut, TBaseElem* elem) = 0;
330};
331
333
369template <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,
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
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
geometry_traits< TElem >::iterator begin(int level)
Definition multi_grid.h:158
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
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
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