ug4
attachment_pipe.h
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 #ifndef __UTIL__ATTACHMENT_PIPE__
34 #define __UTIL__ATTACHMENT_PIPE__
35 
36 #include <list>
37 #include <vector>
38 #include <stack>
39 #include <cassert>
40 #include "common/static_assert.h"
41 #include "common/types.h"
42 #include "common/util/uid.h"
43 #include "common/util/hash.h"
44 #include "common/ug_config.h"
45 #include "page_container.h"
46 
47 namespace ug
48 {
49 
50 // PREDECLARATIONS
51 class IAttachment;
52 class IAttachmentDataContainer;
53 
54 
55 // CONSTANTS
57 {
58  INVALID_ATTACHMENT_INDEX = 0xFFFFFFFF
59 };
60 
61 
63 // IAttachedDataContainer
65 
72 {
73  public:
75 
76  virtual void resize(size_t iSize) = 0;
77  virtual size_t size() = 0;
78  virtual void copy_data(size_t indFrom, size_t indTo) = 0;
79  virtual void reset_entry(size_t index) = 0;
80 
90  int* indexMap, int num) const = 0;
91 
99  virtual void defragment(size_t* pNewIndices, size_t numValidElements) = 0;
100 
102 
103  virtual size_t occupied_memory() = 0;
104 };
105 
108 
110 template <class TValue>
112  typedef TValue& reference;
113  typedef const TValue& const_reference;
114 };
115 
117 template <>
119  typedef std::vector<bool>::reference reference;
120  typedef const std::vector<bool>::reference const_reference;
121 };
122 
123 /* THOUGHTS
124 * AttachmentDataContainer<T> should probably be defined in another header, since it is somehow specialised for libGrid.
125 * same goes for Attachment<T>
126 */
128 // AttachedDataContainer
130 
134 template <class T> class UG_API AttachmentDataContainer : public IAttachmentDataContainer
135 {
136  private:
138  //typedef PageContainer<T> DataContainer;
139  typedef std::vector<T> DataContainer;
142 
143  public:
144  typedef T ValueType;
145 
146  AttachmentDataContainer(const T& defaultValue = T()) : m_defaultValue(defaultValue) {}
147 
148  virtual ~AttachmentDataContainer() {m_vData.clear();}
149 
150  virtual void resize(size_t iSize)
151  {
152  if(iSize > 0)
153  m_vData.resize(iSize, m_defaultValue);
154  else
155  m_vData.clear();
156  }
157 
158  virtual size_t size() {return m_vData.size();}
159 
160  virtual void copy_data(size_t indFrom, size_t indTo) {m_vData[indTo] = m_vData[indFrom];}
161 
162  virtual void reset_entry(size_t index)
163  {
164  m_vData[index] = m_defaultValue;
165  }
166 
167  virtual void defragment(size_t* pNewIndices, size_t numValidElements)
168  {
169  size_t numOldElems = size();
170  DataContainer vDataOld = m_vData;
171  m_vData.resize(numValidElements);
172  for(size_t i = 0; i < numOldElems; ++i)
173  {
174  size_t nInd = pNewIndices[i];
175  if(nInd != INVALID_ATTACHMENT_INDEX)
176  m_vData[nInd] = vDataOld[i];
177  }
178  }
179 
190  int* indexMap, int num) const
191  {
192  ClassType* destConT = dynamic_cast<ClassType*>(pDestCon);
193  assert(destConT && "Type of pDestBuf has to be the same as the"
194  "type of this buffer");
195 
196  if(!destConT)
197  return;
198 
199  DataContainer& dest = destConT->get_data_container();
200  for(int i = 0; i < num; ++i)
201  dest[i] = m_vData[indexMap[i]];
202  }
203 
204 
206  virtual size_t occupied_memory()
207  {
208  return m_vData.capacity() * sizeof(T);
209  }
210 
211  inline TConstRef get_elem(size_t index) const {return m_vData[index];}
212  inline TRef get_elem(size_t index) {return m_vData[index];}
213  inline TConstRef operator[] (size_t index) const {return m_vData[index];}
214  inline TRef operator[] (size_t index) {return m_vData[index];}
215 
217  void swap(AttachmentDataContainer<T>& container) {m_vData.swap(container.m_vData);}
218 
219  protected:
220  DataContainer& get_data_container() {return m_vData;}
221  //inline const T* get_ptr() const {return &m_vData.front();}
222  //inline T* get_ptr() {return &m_vData.front();}
223 
224  protected:
227 };
228 
230 // IAttachment
232 
238 class UG_API IAttachment : public UID
239 {
240  public:
241  IAttachment() : m_name("undefined") {}
242  IAttachment(const char* name) : m_name(name)
243  {assert(m_name);}
244 
245  virtual ~IAttachment() {}
246  virtual IAttachment* clone() = 0;
248  virtual bool default_pass_on_behaviour() const = 0;
249 
250  const char* get_name() {return m_name;}
251 
252  protected:
253  const char* m_name; //only for debug
254 };
255 
257 // Attachment
259 
262 template <class T> class UG_API Attachment : public IAttachment
263 {
264  public:
266  typedef T ValueType;
267 
268  Attachment() : IAttachment(), m_passOnBehaviour(false) {}
269  Attachment(bool passOnBehaviour) : IAttachment(), m_passOnBehaviour(passOnBehaviour) {}
270  Attachment(const char* name) : IAttachment(name), m_passOnBehaviour(false) {}
271  Attachment(const char* name, bool passOnBehaviour) : IAttachment(name), m_passOnBehaviour(passOnBehaviour) {}
272 
273  virtual ~Attachment() {}
274  virtual IAttachment* clone() {IAttachment* pA = new Attachment<T>; *pA = *this; return pA;}
276  virtual bool default_pass_on_behaviour() const {return m_passOnBehaviour;}
277  IAttachmentDataContainer* create_container(const T& defaultValue) {return new ContainerType(defaultValue);}
278 
279  protected:
281 };
282 
284 // AttachmentEntry
287 {
289  AttachmentEntry(IAttachment* pAttachment, IAttachmentDataContainer* pContainer, uint userData = 0) :
290  m_pAttachment(pAttachment), m_pContainer(pContainer), m_userData(userData) {}
291 
295 };
296 
297 
300 
303 template<class TElem, class TElemHandler>
305 {
306  public:
307  typedef TElem& ElemRef;
308  typedef void* ElemPtr;
309  typedef const void* ConstElemPtr;
310  typedef void* ElemHandlerPtr;
311  typedef const void* ConstElemHandlerPtr;
312 
313  typedef void element_iterator;
314 
315  static inline element_iterator elements_begin(ElemHandlerPtr pHandler) {}
316  static inline element_iterator elements_end(ElemHandlerPtr pHandler) {}
317  static inline uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem) {return INVALID_ATTACHMENT_INDEX;/*STATIC_ASSERT(0, INVALID_ATTACHMENT_TRAITS);*/}
318  static inline void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, size_t index) {/*STATIC_ASSERT(0, INVALID_ATTACHMENT_TRAITS);*/}
319 };
320 
322 // AttachmentPipe
324 
335 template<class TElem, class TElemHandler>
337 {
338  public:
339  typedef TElem element;
340  typedef TElemHandler ElementHandler;
341  typedef std::list<AttachmentEntry> AttachmentEntryContainer;
342  typedef AttachmentEntryContainer::iterator AttachmentEntryIterator;
343  typedef AttachmentEntryContainer::const_iterator ConstAttachmentEntryIterator;
346 
347  public:
348  AttachmentPipe();
349  AttachmentPipe(typename atraits::ElemHandlerPtr pHandler);
350  ~AttachmentPipe();
351 
352  inline typename atraits::ElemHandlerPtr get_elem_handler() {return m_pHandler;}
353 
355  void clear();
357  void clear_elements();
359  void clear_attachments();
360 
362 
374  void reserve(size_t numElems);
375 
377 
381  void register_element(TElem elem);
382 
384 
388  void unregister_element(const TElem& elem);
389 
391  void defragment();
392 
407  template <class TAttachment>
408  void attach(TAttachment& attachment,
409  const typename TAttachment::ValueType& defaultValue,
410  uint options);
411 
412  void attach(IAttachment& attachment, uint options = 0);
416  void detach(IAttachment& attachment);
417 
419  bool has_attachment(IAttachment& attachment) const;
420 
422 
434  template <class TAttachment>
435  typename TAttachment::ValueType*
436  get_data_array(TAttachment& attachment);
437 
440  IAttachmentDataContainer* get_data_container(IAttachment& attachment) const;
441 
442  template <class TAttachment>
443  typename TAttachment::ContainerType*
444  get_data_container(TAttachment& attachment);
447  inline ConstAttachmentEntryIterator attachments_begin() const {return m_attachmentEntryContainer.begin();}
448  inline ConstAttachmentEntryIterator attachments_end() const {return m_attachmentEntryContainer.end();}
449 
451  inline size_t num_elements() const {return m_numElements;}
453 
456  inline size_t num_data_entries() const {return m_numDataEntries;}
457 
459 
464  inline bool is_fragmented() const {return m_numElements != m_numDataEntries;}
465 
466  void reset_values(size_t dataIndex);
467 
468  protected:
469  void resize_attachment_containers(size_t newSize);
470  void grow_attachment_containers(size_t newMinSize);
471  inline size_t get_container_size();
472 
473  protected:
474  typedef std::stack<size_t> UINTStack;
475 
476  protected:
479 
481 
485 
487 };
488 
489 
491 // AttachmentAccessor
493 
508 template <class TElem, class TAttachment, class TElemHandler>
510 {
511  public:
512  typedef TAttachment attachment;
513  typedef TElem element;
514  typedef typename TAttachment::ValueType ValueType;
515  typedef typename TAttachment::ContainerType ContainerType;
516  typedef TElemHandler ElemHandler;
519 
520  public:
524 
525  bool access(attachment_pipe& attachmentPipe, TAttachment& attachment);
526 
529  {
531  "ERROR in AttachmentAccessor::operator[]: accessing element with invalid attachment index!");
532  assert(m_pContainer && "ERROR in AttachmentAccessor::operator[]: no AttachmentPipe assigned.");
533  return m_pContainer->get_elem(attachment_traits<TElem, TElemHandler>::get_data_index(m_pHandler, elem));
534  }
535 
537  operator[](typename atraits::ConstElemPtr elem) const
538  {
540  "ERROR in AttachmentAccessor::operator[]: accessing element with invalid attachment index!");
541  assert(m_pContainer && "ERROR in AttachmentAccessor::operator[]: no AttachmentPipe assigned.");
542  return m_pContainer->get_elem(attachment_traits<TElem, TElemHandler>::get_data_index(m_pHandler, elem));
543  }
544 
545 /*
546  inline ValueType&
547  operator[](int index)
548  {
549  assert(m_pContainer && "ERROR in AttachmentAccessor::operator[]: no AttachmentPipe assigned.");
550  return m_pContainer->get_elem(index);
551  }
552 */
553  inline bool valid() const
554  {return m_pContainer != NULL;}
555 
556  inline void invalidate()
557  {m_pContainer = NULL;}
558 
561  {
562  m_pContainer->swap(*acc.m_pContainer);
563  }
564 
566 
570  {
571  if(m_pContainer){
572  if(m_pContainer->size() > 0)
573  return &(*m_pContainer)[0];
574  }
575  return NULL;
576  }
577 
579 
582  {
584  }
585 
586  protected:
588  TElemHandler* m_pHandler;
589 };
590 
591 
592 }// end of namespace
593 
594 // include implementation
595 #include "attachment_pipe.hpp"
596 
597 #endif
location name
Definition: checkpoint_util.lua:128
Used to access data that has been attached to an attachment pipe.
Definition: attachment_pipe.h:510
AttachmentPipe< TElem, TElemHandler > attachment_pipe
Definition: attachment_pipe.h:518
void invalidate()
Definition: attachment_pipe.h:556
TAttachment::ContainerType ContainerType
Definition: attachment_pipe.h:515
bool valid() const
Definition: attachment_pipe.h:553
ValueType * raw_data()
returns the raw pointer to the data of the associated container
Definition: attachment_pipe.h:569
TElemHandler ElemHandler
Definition: attachment_pipe.h:516
TAttachment::ValueType ValueType
Definition: attachment_pipe.h:514
TElem element
Definition: attachment_pipe.h:513
attachment_traits< TElem, TElemHandler > atraits
Definition: attachment_pipe.h:517
TElemHandler * m_pHandler
Definition: attachment_pipe.h:588
attachment_value_traits< ValueType >::const_reference operator[](typename atraits::ConstElemPtr elem) const
Definition: attachment_pipe.h:537
ContainerType * m_pContainer
Definition: attachment_pipe.h:587
TAttachment attachment
Definition: attachment_pipe.h:512
attachment_value_traits< ValueType >::reference operator[](typename atraits::ConstElemPtr elem)
Definition: attachment_pipe.h:528
size_t element_data_index(typename atraits::ConstElemPtr elem)
returns the data index of the given element regarding the associated container.
Definition: attachment_pipe.h:581
void swap(AttachmentAccessor< TElem, TAttachment, TElemHandler > &acc)
calls swap on associated containers
Definition: attachment_pipe.h:560
A generic specialization of IAttachedDataContainer.
Definition: attachment_pipe.h:135
void swap(AttachmentDataContainer< T > &container)
swaps the buffer content of associated data
Definition: attachment_pipe.h:217
AttachmentDataContainer< T > ClassType
Definition: attachment_pipe.h:137
virtual void copy_data(size_t indFrom, size_t indTo)
copy data from entry indFrom to entry indTo.
Definition: attachment_pipe.h:160
virtual size_t size()
returns the size of the data-array.
Definition: attachment_pipe.h:158
std::vector< T > DataContainer
Definition: attachment_pipe.h:139
attachment_value_traits< T >::const_reference TConstRef
Definition: attachment_pipe.h:141
TRef get_elem(size_t index)
Definition: attachment_pipe.h:212
DataContainer m_vData
Definition: attachment_pipe.h:225
virtual ~AttachmentDataContainer()
Definition: attachment_pipe.h:148
virtual void defragment(size_t *pNewIndices, size_t numValidElements)
Definition: attachment_pipe.h:167
virtual void reset_entry(size_t index)
resets the entry to its default value.
Definition: attachment_pipe.h:162
T ValueType
Definition: attachment_pipe.h:144
AttachmentDataContainer(const T &defaultValue=T())
Definition: attachment_pipe.h:146
virtual void copy_to_container(IAttachmentDataContainer *pDestCon, int *indexMap, int num) const
Definition: attachment_pipe.h:189
attachment_value_traits< T >::reference TRef
Definition: attachment_pipe.h:140
TConstRef get_elem(size_t index) const
Definition: attachment_pipe.h:211
virtual void resize(size_t iSize)
resize the data array
Definition: attachment_pipe.h:150
T m_defaultValue
Definition: attachment_pipe.h:226
virtual size_t occupied_memory()
returns the memory occupied by the container
Definition: attachment_pipe.h:206
DataContainer & get_data_container()
Definition: attachment_pipe.h:220
A generic specialization of IAttachment.
Definition: attachment_pipe.h:263
AttachmentDataContainer< T > ContainerType
Definition: attachment_pipe.h:265
virtual IAttachmentDataContainer * create_container()
Definition: attachment_pipe.h:275
Attachment(bool passOnBehaviour)
Definition: attachment_pipe.h:269
IAttachmentDataContainer * create_container(const T &defaultValue)
Definition: attachment_pipe.h:277
Attachment(const char *name, bool passOnBehaviour)
Definition: attachment_pipe.h:271
Attachment(const char *name)
Definition: attachment_pipe.h:270
T ValueType
Definition: attachment_pipe.h:266
bool m_passOnBehaviour
Definition: attachment_pipe.h:280
virtual IAttachment * clone()
Definition: attachment_pipe.h:274
Attachment()
Definition: attachment_pipe.h:268
virtual bool default_pass_on_behaviour() const
Definition: attachment_pipe.h:276
virtual ~Attachment()
Definition: attachment_pipe.h:273
Handles data which has been attached to the pipe using callbacks for the element.
Definition: attachment_pipe.h:337
ConstAttachmentEntryIterator attachments_begin() const
Definition: attachment_pipe.h:447
AttachmentEntryIteratorHash m_attachmentEntryIteratorHash
Definition: attachment_pipe.h:478
size_t num_data_entries() const
Returns the size of the associated data arrays.
Definition: attachment_pipe.h:456
std::list< AttachmentEntry > AttachmentEntryContainer
Definition: attachment_pipe.h:341
AttachmentEntryContainer m_attachmentEntryContainer
Definition: attachment_pipe.h:477
std::stack< size_t > UINTStack
Definition: attachment_pipe.h:474
TElemHandler ElementHandler
Definition: attachment_pipe.h:340
atraits::ElemHandlerPtr m_pHandler
Definition: attachment_pipe.h:486
size_t m_containerSize
total size of containers.
Definition: attachment_pipe.h:484
ConstAttachmentEntryIterator attachments_end() const
Definition: attachment_pipe.h:448
TElem element
Definition: attachment_pipe.h:339
UINTStack m_stackFreeEntries
holds indices to free entries.
Definition: attachment_pipe.h:480
AttachmentEntryContainer::iterator AttachmentEntryIterator
Definition: attachment_pipe.h:342
size_t m_numElements
Definition: attachment_pipe.h:482
attachment_traits< TElem, TElemHandler > atraits
Definition: attachment_pipe.h:345
size_t m_numDataEntries
Definition: attachment_pipe.h:483
Hash< uint, AttachmentEntryIterator > AttachmentEntryIteratorHash
Definition: attachment_pipe.h:344
bool is_fragmented() const
Returns whether the attachment pipe is fragmented.
Definition: attachment_pipe.h:464
size_t num_elements() const
Returns the number of registered elements.
Definition: attachment_pipe.h:451
AttachmentEntryContainer::const_iterator ConstAttachmentEntryIterator
Definition: attachment_pipe.h:343
atraits::ElemHandlerPtr get_elem_handler()
Definition: attachment_pipe.h:352
the interface for an attachment-data-container.
Definition: attachment_pipe.h:72
virtual size_t occupied_memory()=0
returns the size in bytes, which the container occupies
virtual void reset_entry(size_t index)=0
resets the entry to its default value.
virtual void defragment(size_t *pNewIndices, size_t numValidElements)=0
virtual size_t size()=0
returns the size of the data-array.
virtual void copy_data(size_t indFrom, size_t indTo)=0
copy data from entry indFrom to entry indTo.
virtual void copy_to_container(IAttachmentDataContainer *pDestCon, int *indexMap, int num) const =0
virtual ~IAttachmentDataContainer()
Definition: attachment_pipe.h:74
virtual void resize(size_t iSize)=0
resize the data array
the interface for attachments.
Definition: attachment_pipe.h:239
virtual IAttachment * clone()=0
const char * get_name()
should only be used for debug purposes.
Definition: attachment_pipe.h:250
virtual ~IAttachment()
Definition: attachment_pipe.h:245
IAttachment()
Definition: attachment_pipe.h:241
virtual IAttachmentDataContainer * create_container()=0
virtual bool default_pass_on_behaviour() const =0
IAttachment(const char *name)
Definition: attachment_pipe.h:242
const char * m_name
Definition: attachment_pipe.h:253
supplies a unique ID.
Definition: uid.h:50
define the interface that enables you to use your own types as element-types in an AttachmentPipe.
Definition: attachment_pipe.h:305
void * ElemPtr
Definition: attachment_pipe.h:308
const void * ConstElemHandlerPtr
Definition: attachment_pipe.h:311
const void * ConstElemPtr
Definition: attachment_pipe.h:309
void element_iterator
Definition: attachment_pipe.h:313
static void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, size_t index)
Definition: attachment_pipe.h:318
static element_iterator elements_end(ElemHandlerPtr pHandler)
Definition: attachment_pipe.h:316
TElem & ElemRef
Definition: attachment_pipe.h:307
static element_iterator elements_begin(ElemHandlerPtr pHandler)
Definition: attachment_pipe.h:315
void * ElemHandlerPtr
Definition: attachment_pipe.h:310
static uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem)
Definition: attachment_pipe.h:317
virtual void clear_attachments(typename TDomain::grid_type &grid)
#define UG_API
Definition: ug_config.h:65
unsigned int uint
Definition: types.h:114
the ug namespace
ATTACHMENT_CONSTANTS
Definition: attachment_pipe.h:57
@ INVALID_ATTACHMENT_INDEX
Definition: attachment_pipe.h:58
void defragment()
This struct is used by AttachmentPipe in order to manage its attachments.
Definition: attachment_pipe.h:287
AttachmentEntry()
Definition: attachment_pipe.h:288
uint m_userData
Definition: attachment_pipe.h:294
IAttachmentDataContainer * m_pContainer
Definition: attachment_pipe.h:293
IAttachment * m_pAttachment
Definition: attachment_pipe.h:292
AttachmentEntry(IAttachment *pAttachment, IAttachmentDataContainer *pContainer, uint userData=0)
Definition: attachment_pipe.h:289
std::vector< bool >::reference reference
Definition: attachment_pipe.h:119
const std::vector< bool >::reference const_reference
Definition: attachment_pipe.h:120
define reference and const reference types for attachment values.
Definition: attachment_pipe.h:111
TValue & reference
Definition: attachment_pipe.h:112
const TValue & const_reference
Definition: attachment_pipe.h:113