ug4
copy_attachment_handler.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015: G-CSC, Goethe University Frankfurt
3  * Author: Markus Breit
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 LIB_GRID__COPY_ATTACHMENT_HANDLER_H_
34 #define LIB_GRID__COPY_ATTACHMENT_HANDLER_H_
35 
36 #include "common/util/smart_pointer.h" // for SmartPtr
37 #include "lib_grid/grid/grid_observer.h" // for GridObserver
38 #include "lib_grid/multi_grid.h" // for MultiGrid
39 
40 #ifdef UG_PARALLEL
41  #include "lib_grid/parallelization/util/compol_copy_attachment.h" // ComPol_CopyAttachment
42  #include "lib_grid/parallelization/distributed_grid.h" // DistributedGridManager
43 #endif
44 
45 namespace ug{
46 
47 
101 template <typename TElem, typename TAttachment>
103 {
104  public:
107  : m_bEnableVertComm(true) {}
108 
111  {
112  if (m_spMG.valid())
113  m_spMG->unregister_observer(this);
114 
115  m_aa.invalidate();
116  };
117 
118  void set_attachment(const TAttachment& attch)
119  {
120  m_a = attch;
121 
122  // if we already have a grid, then this must be a reset
123  if (m_spMG.valid())
124  {
125  m_aa.invalidate();
126  m_aa.access(*m_spMG, m_a);
127  }
128  }
129 
131  {
132  // do nothing if given grid is already set
133  if (m_spMG == mg) return;
134 
135  // if another grid is already given, unregister from old grid and invalidate accessor
136  if (m_spMG.valid())
137  {
138  m_spMG->unregister_observer(this);
139  m_aa.invalidate();
140  }
141 
142  // set new grid
143  m_spMG = mg;
144  UG_COND_THROW(!m_spMG.valid(), "No valid multigrid given!");
145 
146  // register as appropriate observer
148 
149  // check that attachment is attached to grid
150  UG_COND_THROW(!m_spMG->has_attachment<TElem>(m_a),
151  "Given grid does not have given attachment attached to it.");
152 
153  // init accessor
154  m_aa.access(*m_spMG, m_a);
155 
156  // copy to all levels that are already present
158  }
159 
161  {
162  m_bEnableVertComm = b;
163  }
164 
165 
166  // GridObserver implementations
167  virtual void vertex_created
168  (
169  Grid* grid,
170  Vertex* vrt,
171  GridObject* pParent = NULL,
172  bool replacesParent = false
173  )
174  {
175  propagate<Vertex, void>(vrt, pParent, this);
176  }
177 
178  virtual void edge_created
179  (
180  Grid* grid,
181  Edge* e,
182  GridObject* pParent = NULL,
183  bool replacesParent = false
184  )
185  {
186  propagate<Edge, void>(e, pParent, this);
187  }
188 
189  virtual void face_created
190  (
191  Grid* grid,
192  Face* f,
193  GridObject* pParent = NULL,
194  bool replacesParent = false
195  )
196  {
197  propagate<Face, void>(f, pParent, this);
198  }
199 
200  virtual void volume_created
201  (
202  Grid* grid,
203  Volume* vol,
204  GridObject* pParent = NULL,
205  bool replacesParent = false
206  )
207  {
208  propagate<Volume, void>(vol, pParent, this);
209  }
210 
211  protected:
212 
213  // this template will be used if created is called with anything BUT TElem (in that case: do nothing)
214  template <typename TCreatedElem, typename Dummy>
215  struct propagate
216  {
217  propagate(TCreatedElem* elem, GridObject* pParent, CopyAttachmentHandler<TElem, TAttachment>* cah) {};
218  };
219 
220  // this template will be used if created is called with an elem of type TElem
221  template <typename Dummy>
222  struct propagate<TElem, Dummy>
223  {
225  {
226  // check that parent is given
227  if (!pParent) return;
228 
229  // if parent is of different elem type than child
230  TElem* par = dynamic_cast<TElem*>(pParent);
231  if (!par)
232  {
233  cah->copy_from_other_elem_type(pParent, elem);
234  return;
235  }
236 
237  // copy attachment value from parent to child
238  cah->copy(par, elem);
239  }
240  };
241 
242  friend struct propagate<TElem, void>;
243 
244  template <typename TObserverElem, typename Dummy>
246  {
248  };
249 
250  template <typename Dummy>
252  {
254  {
255  mg->register_observer(cah, OT_VERTEX_OBSERVER);
256  }
257  };
258  template <typename Dummy>
259  struct register_as_observer<Edge, Dummy>
260  {
262  {
263  mg->register_observer(cah, OT_EDGE_OBSERVER);
264  }
265  };
266  template <typename Dummy>
267  struct register_as_observer<Face, Dummy>
268  {
270  {
271  mg->register_observer(this, OT_FACE_OBSERVER);
272  }
273  };
274  template <typename Dummy>
276  {
278  {
279  mg->register_observer(this, OT_VOLUME_OBSERVER);
280  }
281  };
282 
283 
285  {
286  // ensure a final vertical communication on the top level
287  const size_t nProp = m_bEnableVertComm ? m_spMG->num_levels() + 1 : m_spMG->num_levels();
288  for (size_t i = 1; i < nProp; ++i)
290  }
291 
292  void propagate_to_level(size_t lvl, bool vertComm = true)
293  {
294 #ifdef UG_PARALLEL
295  // copy from vMasters to vSlaves
296  if (pcl::NumProcs() > 1 && vertComm)
297  {
298  typedef typename GridLayoutMap::Types<TElem>::Layout layout_type;
299  DistributedGridManager& dgm = *m_spMG->distributed_grid_manager();
300  GridLayoutMap& glm = dgm.grid_layout_map();
302 
304  icom.exchange_data(glm, INT_V_MASTER, INT_V_SLAVE, compolCopy);
305  icom.communicate();
306  }
307 #endif
308  // iterate over all TElems of level
309  typedef typename geometry_traits<TElem>::const_iterator iter_type;
310  iter_type iter = m_spMG->begin<TElem>(lvl);
311  iter_type iter_end = m_spMG->end<TElem>(lvl);
312  for (; iter != iter_end; ++iter)
313  {
314  TElem* child = *iter;
315  GridObject* parent = m_spMG->get_parent(*iter);
316 
317  propagate<TElem, void>(child, parent, this);
318  }
319  }
320 
321  virtual void copy(TElem* parent, TElem* child)
322  {
323  m_aa[child] = m_aa[parent];
324  }
325 
326  virtual void copy_from_other_elem_type(GridObject* parent, TElem* child) {};
327 
328  protected:
331 
333 
335  TAttachment m_a;
336 
339 
340 };
341 
342 } // end namespace ug
343 
344 #endif // LIB_GRID__COPY_ATTACHMENT_HANDLER_H__
bool valid() const
returns true if the pointer is valid, false if not.
Definition: smart_pointer.h:206
Performs communication between interfaces on different processes.
Definition: pcl_interface_communicator.h:68
bool communicate(int tag=749345)
sends and receives the collected data.
Definition: pcl_interface_communicator_impl.hpp:409
void exchange_data(const TLayoutMap &layoutMap, const typename TLayoutMap::Key &keyFrom, const typename TLayoutMap::Key &keyTo, ICommunicationPolicy< TLayout > &commPol)
internally calls send_data and receive_data with the specified layouts.
Definition: pcl_interface_communicator_impl.hpp:213
the standard multi-level-layout implementation
Definition: pcl_communication_structs.h:615
copies values from a specified attachment to a stream and back.
Definition: compol_copy_attachment.h:54
handler for attachments in a multi-grid
Definition: copy_attachment_handler.h:103
virtual void volume_created(Grid *grid, Volume *vol, GridObject *pParent=NULL, bool replacesParent=false)
Notified whenever a new element of the given type is created in the given grid.
Definition: copy_attachment_handler.h:201
void set_grid(SmartPtr< MultiGrid > mg)
Definition: copy_attachment_handler.h:130
virtual ~CopyAttachmentHandler()
destructor
Definition: copy_attachment_handler.h:110
void set_attachment(const TAttachment &attch)
Definition: copy_attachment_handler.h:118
virtual void face_created(Grid *grid, Face *f, GridObject *pParent=NULL, bool replacesParent=false)
Notified whenever a new element of the given type is created in the given grid.
Definition: copy_attachment_handler.h:190
CopyAttachmentHandler()
constructor
Definition: copy_attachment_handler.h:106
void propagate_to_levels()
Definition: copy_attachment_handler.h:284
virtual void edge_created(Grid *grid, Edge *e, GridObject *pParent=NULL, bool replacesParent=false)
Notified whenever a new element of the given type is created in the given grid.
Definition: copy_attachment_handler.h:179
virtual void copy_from_other_elem_type(GridObject *parent, TElem *child)
Definition: copy_attachment_handler.h:326
void enable_vertical_communication(bool b)
Definition: copy_attachment_handler.h:160
void propagate_to_level(size_t lvl, bool vertComm=true)
Definition: copy_attachment_handler.h:292
friend struct propagate< TElem, void >
Definition: copy_attachment_handler.h:242
virtual void copy(TElem *parent, TElem *child)
Definition: copy_attachment_handler.h:321
TAttachment m_a
attachment to be handled
Definition: copy_attachment_handler.h:335
virtual void vertex_created(Grid *grid, Vertex *vrt, GridObject *pParent=NULL, bool replacesParent=false)
Notified whenever a new element of the given type is created in the given grid.
Definition: copy_attachment_handler.h:168
Grid::AttachmentAccessor< TElem, TAttachment > m_aa
accessor for handled attachment
Definition: copy_attachment_handler.h:338
bool m_bEnableVertComm
Definition: copy_attachment_handler.h:332
SmartPtr< MultiGrid > m_spMG
multigrid
Definition: copy_attachment_handler.h:326
manages the layouts and interfaces which are associated with a distributed grid.
Definition: distributed_grid.h:88
GridLayoutMap & grid_layout_map()
Definition: distributed_grid.h:103
Base-class for edges.
Definition: grid_base_objects.h:397
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
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
lets you access layouts by type and key
Definition: parallel_grid_layout.h:152
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition: grid_base_objects.h:157
Definition: grid_observer.h:80
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
int NumProcs()
returns the number of processes
Definition: pcl_base.cpp:91
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
the ug namespace
@ OT_VERTEX_OBSERVER
Definition: grid_observer.h:55
@ OT_VOLUME_OBSERVER
Definition: grid_observer.h:58
@ OT_FACE_OBSERVER
Definition: grid_observer.h:57
@ OT_EDGE_OBSERVER
Definition: grid_observer.h:56
@ INT_V_MASTER
vertical master node
Definition: parallel_grid_layout.h:106
@ INT_V_SLAVE
vertical slave node
Definition: parallel_grid_layout.h:107
propagate(TElem *elem, GridObject *pParent, CopyAttachmentHandler< TElem, TAttachment > *cah)
Definition: copy_attachment_handler.h:224
Definition: copy_attachment_handler.h:216
propagate(TCreatedElem *elem, GridObject *pParent, CopyAttachmentHandler< TElem, TAttachment > *cah)
Definition: copy_attachment_handler.h:217
register_as_observer(SmartPtr< MultiGrid > mg, CopyAttachmentHandler< Edge, TAttachment > *cah)
Definition: copy_attachment_handler.h:261
register_as_observer(SmartPtr< MultiGrid > mg, CopyAttachmentHandler< Face, TAttachment > *cah)
Definition: copy_attachment_handler.h:269
register_as_observer(SmartPtr< MultiGrid > mg, CopyAttachmentHandler< Vertex, TAttachment > *cah)
Definition: copy_attachment_handler.h:253
register_as_observer(SmartPtr< MultiGrid > mg, CopyAttachmentHandler< Volume, TAttachment > *cah)
Definition: copy_attachment_handler.h:277
Definition: copy_attachment_handler.h:246
register_as_observer(SmartPtr< MultiGrid > mg, CopyAttachmentHandler< TObserverElem, TAttachment > *cah)
Definition: copy_attachment_handler.h:247