ug4
multi_grid_impl.hpp
Go to the documentation of this file.
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 "common/static_assert.h"
34 #include "multi_grid.h"
35 
36 #ifndef __H__LIB_GRID__MULTI_GRID_IMPL__
37 #define __H__LIB_GRID__MULTI_GRID_IMPL__
38 
39 namespace ug
40 {
41 /*
42 template <class TChild, class TElem>
43 int MultiGrid::num_children(TElem* elem)
44 {
45 
46  int sharedPipeSec = elem->container_section();
47  assert(sharedPipeSec != -1 && "bad shared pipe section!");
48 
49  return get_elem_info(elem)->m_children.num_elements(sharedPipeSec);
50 }
51 
52 // child access
53 template <class TChild, class TElem>
54 int MultiGrid::get_children(std::vector<TChild*>& vChildrenOut, TElem* elem)
55 {
56 
57  int sharedPipeSec = geometry_traits<TChild>::CONTAINER_SECTION;
58  assert(sharedPipeSec != -1 && "bad shared pipe section!");
59 
60  MGElementInfo* elemInfo = get_elem_info(elem);
61 
62  typename SectionContainer::iterator iter =
63  elemInfo->m_children.section_begin(sharedPipeSec);
64 
65  typename SectionContainer::iterator iterEnd =
66  elemInfo->m_children.section_end(sharedPipeSec);
67 
68  int numChildren = elemInfo->m_children.num_elements(sharedPipeSec);
69 
70  if(vChildrenOut.capacity() < numChildren)
71  vChildrenOut.reserve(numChildren);
72 
73  vChildrenOut.clear();
74 
75  for(; iter != iterEnd; ++iter)
76  {
77  vChildrenOut.push_back((TChild*) *iter);
78  }
79 
80  return vChildrenOut.size();
81 
82 }
83 */
84 
85 inline size_t MultiGrid::
86 top_level() const
87 {
88  if(m_hierarchy.num_subsets() <= 0) return 0;
89  return size_t(m_hierarchy.num_subsets() - 1);
90 }
91 
92 template <class TElem>
94 num_children_total(TElem* elem) const
95 {
96  size_t numChildren = num_children<TElem>(elem);
97  size_t numChildrenTotal = numChildren;
98 
99  for(size_t i = 0; i < numChildren; ++i)
100  numChildrenTotal += num_children_total(get_child<TElem>(elem, i));
101 
102  return numChildrenTotal;
103 }
104 
105 
106 template<class TGeomObj>
108 MultiGrid::create(size_t level)
109 {
111  Grid::create<TGeomObj>();
112 // put the element into the hierarchy
113 // (by default it already was assigned to level 0)
114  if(level > 0){
115  level_required(level);
116  m_hierarchy.assign_subset(*iter, level);
117  }
118  return iter;
119 }
120 
121 template <class TGeomObj>
124  size_t level)
125 {
127  Grid::create<TGeomObj>(descriptor);
128 // put the element into the hierarchy
129 // (by default it already was assigned to level 0)
130  if(level > 0){
131  level_required(level);
132  m_hierarchy.assign_subset(*iter, level);
133  }
134  return iter;
135 }
136 
137 inline void MultiGrid::level_required(int lvl)
138 {
139  if(m_hierarchy.num_subsets() <= lvl){
141  }
142 }
143 
144 
145 template <class TChild>
147 {
148  switch(elem->base_object_id()){
149  case VERTEX: return num_children<TChild>(static_cast<Vertex*>(elem));
150  case EDGE: return num_children<TChild>(static_cast<Edge*>(elem));
151  case FACE: return num_children<TChild>(static_cast<Face*>(elem));
152  case VOLUME: return num_children<TChild>(static_cast<Volume*>(elem));
153  }
154  return 0;
155 }
156 
157 template <class TChild>
158 TChild* MultiGrid::get_child(GridObject* elem, size_t ind) const
159 {
160  switch(elem->base_object_id()){
161  case VERTEX: return get_child<TChild>(static_cast<Vertex*>(elem), ind);
162  case EDGE: return get_child<TChild>(static_cast<Edge*>(elem), ind);
163  case FACE: return get_child<TChild>(static_cast<Face*>(elem), ind);
164  case VOLUME: return get_child<TChild>(static_cast<Volume*>(elem), ind);
165  }
166  return NULL;
167 }
168 
169 template <class TElem>
171 clear_child_connections(TElem* parent)
172 {
173  if(has_children(parent))
174  get_info(parent).unregister_from_children(*this);
175 }
176 
177 template <class TElem>
179 associate_parent(TElem* elem, GridObject* parent)
180 {
181  if(elem->base_object_id() > parent->base_object_id()){
182  UG_THROW("Dimension of parent too low.");
183  }
184 
185  GridObject* oldParent = get_parent(elem);
186  if(oldParent == parent)
187  return;
188 
189  if(oldParent)
190  remove_child(oldParent, elem);
191 
192  if(parent){
193  add_child(parent, elem);
194  set_parent_type(elem, (char)parent->base_object_id());
195  }
196 
197  set_parent(elem, parent);
198 }
199 
200 template <class TElem>
202 parent_type(TElem* elem) const
203 {
204  return m_aaParentType[elem];
205 }
206 
207 template <class TElem>
209 set_parent_type(TElem* elem, char type)
210 {
211  m_aaParentType[elem] = type;
212 }
213 
214 // info-access
216 {
217  return m_aaVrtInf[v];
218 }
219 
221 {
222  return m_aaEdgeInf[e];
223 }
224 
226 {
227  if(FaceInfo* info = m_aaFaceInf[f])
228  return *info;
229  UG_THROW("MultiGrid::get_info(...): No face info available!");
230 }
231 
233 {
234  if(VolumeInfo* info = m_aaVolInf[v])
235  return *info;
236  UG_THROW("MultiGrid::get_info(...): No vertex info available!");
237 }
238 
239 // const info-access
241 {
242  return m_aaVrtInf[v];
243 }
244 
246 {
247  return m_aaEdgeInf[e];
248 }
249 
251 {
252  static FaceInfo emptyInfo;
253  if(FaceInfo* info = m_aaFaceInf[f])
254  return *info;
255  return emptyInfo;
256 }
257 
259 {
260  static VolumeInfo emptyInfo;
261  if(VolumeInfo* info = m_aaVolInf[v])
262  return *info;
263  return emptyInfo;
264 }
265 
266 template <class TParent, class TChild>
267 void MultiGrid::add_child(TParent* p, TChild* c)
268 {
270  get_info(p).add_child(c);
271 }
272 
273 template <class TChild>
274 void MultiGrid::add_child(GridObject* p, TChild* c)
275 {
276  switch(p->base_object_id()){
277  case VERTEX: add_child(static_cast<Vertex*>(p), c); break;
278  case EDGE: add_child(static_cast<Edge*>(p), c); break;
279  case FACE: add_child(static_cast<Face*>(p), c); break;
280  case VOLUME: add_child(static_cast<Volume*>(p), c); break;
281  }
282 }
283 
284 template <class TParent, class TChild>
285 void MultiGrid::remove_child(TParent* p, TChild* c)
286 {
287  get_info(p).remove_child(c);
288 }
289 
290 template <class TChild>
292 {
293  switch(p->base_object_id()){
294  case VERTEX: remove_child(static_cast<Vertex*>(p), c); break;
295  case EDGE: remove_child(static_cast<Edge*>(p), c); break;
296  case FACE: remove_child(static_cast<Face*>(p), c); break;
297  case VOLUME: remove_child(static_cast<Volume*>(p), c); break;
298  }
299 }
300 
301 template <class TElem, class TParent>
302 void MultiGrid::element_created(TElem* elem, TParent* pParent)
303 {
304 // if hierarchical_insertion is enabled, the element will be put
305 // into the next higher level of pParents level.
306 
307  int level = 0;
308  if(pParent)
309  {
310  // the element is inserted into a new layer.
311  level = get_level(pParent) + 1;
312  set_parent_type(elem, pParent->base_object_id());
313  }
314  else
315  set_parent_type(elem, -1);
316 
317 // register parent and child
318  //typename mginfo_traits<TElem>::info_type& info = get_info(elem);
319  //info.m_pParent = pParent;
320  set_parent(elem, pParent);
321  if(pParent)
322  {
323  // make sure that the parent has an info object
324  create_child_info(pParent);
325 
326  // add the element to the parents children list
327  typename mginfo_traits<TParent>::info_type& parentInfo = get_info(pParent);
328  parentInfo.add_child(elem);
329  }
330 
331 // put the element into the hierarchy
332  level_required(level);
333  m_hierarchy.assign_subset(elem, level);
334 }
335 
336 template <class TElem, class TParent>
337 void MultiGrid::element_created(TElem* elem, TParent* pParent,
338  TElem* pReplaceMe)
339 {
340  UG_ASSERT(pReplaceMe, "Only call this method with a valid element which shall be replaced.");
341  int level = get_level(pReplaceMe);
342 
343 // register parent and child
344  set_parent(elem, pParent);
345 
346  if(pParent)
347  {
348  // add the element to the parents children list
349  // pParent should have an info object at this time!
350  typename mginfo_traits<TParent>::info_type& parentInfo = get_info(pParent);
351  parentInfo.replace_child(elem, pReplaceMe);
352  }
353 
354 // put the element into the hierarchy
355  level_required(level);
356  m_hierarchy.assign_subset(elem, level);
357 
358 // explicitly copy the parent-type from pReplaceMe to the new vrt.
359 // This has to be done explicitly since a parent may not exist locally in
360 // a parallel environment.
361  set_parent_type(elem, parent_type(pReplaceMe));
362 }
363 
364 template <class TElem>
366 {
367 // we have to remove the elements children as well.
368  if(has_children(elem)){
369  get_info(elem).unregister_from_children(*this);
370  }
371 // we have to remove the associated info object
372  release_child_info(elem);
373 }
374 
375 template <class TElem, class TParent>
376 void MultiGrid::element_to_be_erased(TElem* elem, TParent* pParent)
377 {
378 // unregister the element from its parent.
379 // parents always have an info object
380  typename mginfo_traits<TParent>::info_type& parentInfo = get_info(pParent);
381  parentInfo.remove_child(elem);
382  element_to_be_erased(elem);
383  if(!parentInfo.has_children()){
384  release_child_info(pParent);
385  }
386 }
387 
388 /*
389 template <class TElem>
390 void MultiGrid::element_to_be_replaced(TElem* elemOld, TElem* elemNew)
391 {
392 }
393 */
394 
395 
396 
399 // specialization of wrapper classes
400 
402 // specialization for Grid
403 template <>
405 {
406  public:
407  MGWrapper(Grid& grid) : m_grid(grid) {}
408 
409  inline uint num_levels() const
410  {return 1;}
411 
412  template <class TElem> inline
413  uint num(int level) const
414  {return m_grid.num<TElem>();}
415 
416  template <class TElem> inline
418  begin(int level)
419  {return m_grid.begin<TElem>();}
420 
421  template <class TElem> inline
423  end(int level)
424  {return m_grid.end<TElem>();}
425 
426  protected:
428 };
429 
431 // specialization for MultiGrid
432 template <>
434 {
435  public:
436  MGWrapper(MultiGrid& grid) : m_grid(grid) {}
437 
438  inline uint num_levels() const
439  {return (uint)m_grid.num_levels();}
440 
441  template <class TElem> inline
442  uint num(int level) const
443  {return m_grid.num<TElem>(level);}
444 
445  template <class TElem> inline
447  begin(int level)
448  {return m_grid.begin<TElem>(level);}
449 
450  template <class TElem> inline
452  end(int level)
453  {return m_grid.end<TElem>(level);}
454 
455  protected:
457 };
458 
459 }// end of namespace
460 
461 #endif
parameterString p
Base-class for edges.
Definition: grid_base_objects.h:397
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
virtual int base_object_id() const =0
void assign_subset(Vertex *elem, int subsetIndex)
assigns a vertex to a subset.
Definition: subset_handler_grid.cpp:204
int num_subsets() const
returns the number of subset-infos (return value is int, since SubsetIndices are of type int)
Definition: subset_handler_interface.h:317
uint num(int level) const
Definition: multi_grid_impl.hpp:413
MGWrapper(Grid &grid)
Definition: multi_grid_impl.hpp:407
Grid & m_grid
Definition: multi_grid_impl.hpp:427
geometry_traits< TElem >::iterator begin(int level)
Definition: multi_grid_impl.hpp:418
uint num_levels() const
Definition: multi_grid_impl.hpp:409
geometry_traits< TElem >::iterator end(int level)
Definition: multi_grid_impl.hpp:423
geometry_traits< TElem >::iterator end(int level)
Definition: multi_grid_impl.hpp:452
uint num(int level) const
Definition: multi_grid_impl.hpp:442
uint num_levels() const
Definition: multi_grid_impl.hpp:438
MGWrapper(MultiGrid &grid)
Definition: multi_grid_impl.hpp:436
MultiGrid & m_grid
Definition: multi_grid_impl.hpp:456
geometry_traits< TElem >::iterator begin(int level)
Definition: multi_grid_impl.hpp:447
Definition: multi_grid.h:569
Definition: multi_grid.h:72
int get_level(TElem *elem) const
Definition: multi_grid.h:206
void associate_parent(TElem *elem, GridObject *parent)
establishes a parent child connection between the given elements
Definition: multi_grid_impl.hpp:179
size_t top_level() const
index of the highest level.
Definition: multi_grid_impl.hpp:86
size_t num_children_total(TElem *elem) const
returns the total number of children and grand-children.
Definition: multi_grid_impl.hpp:94
Grid::EdgeAttachmentAccessor< AEdgeInfo > m_aaEdgeInf
Definition: multi_grid.h:549
TChild * get_child(TElem *elem, size_t ind) const
returns the i-th child of the given child-type
Definition: multi_grid.h:268
char parent_type(TElem *elem) const
returns the object-type of the parent of a given object
Definition: multi_grid_impl.hpp:202
VertexInfo & get_info(Vertex *v)
Definition: multi_grid_impl.hpp:215
GridObject * get_parent(GridObject *parent) const
Definition: multi_grid.cpp:180
Grid::VolumeAttachmentAccessor< AVolumeInfo > m_aaVolInf
Definition: multi_grid.h:551
void create_levels(int numLevels)
Definition: multi_grid.cpp:109
void remove_child(TParent *p, TChild *c)
removes a child from the given object
Definition: multi_grid_impl.hpp:285
bool has_children(TElem *elem) const
Definition: multi_grid.h:217
void set_parent_type(TElem *elem, char type)
sets the object-type of the parent of a given object
Definition: multi_grid_impl.hpp:209
void level_required(int lvl)
creates new (empty) levels until num_levels() == lvl+1
Definition: multi_grid_impl.hpp:137
SubsetHandler m_hierarchy
Definition: multi_grid.h:530
void element_created(TElem *elem)
Definition: multi_grid.h:427
Grid::VertexAttachmentAccessor< AVertexInfo > m_aaVrtInf
Definition: multi_grid.h:548
size_t num_children(TElem *elem) const
returns the number of children of the given child-type
Definition: multi_grid.h:225
geometry_traits< TGeomObj >::iterator create(size_t level)
create a custom element on a specific level.
Definition: multi_grid_impl.hpp:108
void clear_child_connections(TElem *parent)
clears the relation between a parent and its children
Definition: multi_grid_impl.hpp:171
void release_child_info(Vertex *o)
releases the info-object for the given object (if necessary)
Definition: multi_grid.h:522
void set_parent(Vertex *o, GridObject *p)
sets the parent for the given object
Definition: multi_grid.h:488
void add_child(TParent *p, TChild *c)
adds a child to the given object
Definition: multi_grid_impl.hpp:267
MultiElementAttachmentAccessor< AParentType > m_aaParentType
Definition: multi_grid.h:553
void create_child_info(Vertex *o)
creates the info-object for the given object (if necessary)
Definition: multi_grid.h:514
Grid::FaceAttachmentAccessor< AFaceInfo > m_aaFaceInf
Definition: multi_grid.h:550
void element_to_be_erased(TElem *elem)
this method is called for elements that havn't got any parent.
Definition: multi_grid_impl.hpp:365
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
Volumes are 3-dimensional objects.
Definition: grid_base_objects.h:754
Definition: grid_base_object_traits.h:68
access to connected types. used internally
Definition: multi_grid_child_info.h:205
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_THROW(msg)
Definition: error.h:57
unsigned int uint
Definition: types.h:114
the ug namespace
@ VOLUME
Definition: grid_base_objects.h:63
@ VERTEX
Definition: grid_base_objects.h:60
@ EDGE
Definition: grid_base_objects.h:61
@ FACE
Definition: grid_base_objects.h:62
Holds information about edge relations. Used internally.
Definition: multi_grid_child_info.h:95
Holds information about face relations. Used internally.
Definition: multi_grid_child_info.h:126
Holds information about vertex relations. Used internally.
Definition: multi_grid_child_info.h:63
void unregister_from_children(MultiGrid &mg)
Definition: multi_grid.cpp:594
void add_child(Vertex *elem)
Definition: multi_grid_child_info.h:67
void remove_child(Vertex *elem)
Definition: multi_grid_child_info.h:71
Holds information about volume relations. Used internally.
Definition: multi_grid_child_info.h:162