ug4
global_attachments.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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__UG_global_attachments
34 #define __H__UG_global_attachments
35 
39 #include <algorithm>
40 
41 namespace ug{
42 
45  public:
46  template <class TAttachment>
47  static void declare_attachment (const std::string& name,
48  bool passOnBehaviour = false)
49  {
50  const char* typeName = attachment_info_traits<TAttachment>::type_name();
51  if(attachments()[name].attachment != NULL) {
53  dynamic_cast<TAttachment*> (attachments()[name].attachment) == NULL,
54  "Attachment with name '" << name
55  << "' was already declared in GlobalAttachments with a different type. "
56  << "Old type: " << attachments()[name].type <<
57  ", new type: " << typeName);
58  return;
59  }
60 
61  int fi = static_cast<int> (attachment_names().size());
62  attachment_names().push_back(name);
63  attachments()[name] =
64  AttachmentEntry(new TAttachment(passOnBehaviour), typeName, fi);
65  functions<Vertex>().push_back(FunctionEntry<Vertex, TAttachment>());
66  functions<Edge>().push_back(FunctionEntry<Edge, TAttachment>());
67  functions<Face>().push_back(FunctionEntry<Face, TAttachment>());
68  functions<Volume>().push_back(FunctionEntry<Volume, TAttachment>());
69  }
70 
71  template <class TAttachment>
72  static void undeclare_attachment(const std::string& name) {
73  UG_COND_THROW(!is_declared(name), "Trying undeclaring a non-declared attachment.");
75  remove_function_entry<Volume>(ae);
76  remove_function_entry<Face>(ae);
77  remove_function_entry<Edge>(ae);
78  remove_function_entry<Vertex>(ae);
79  attachment_names().erase(std::remove(attachment_names().begin(), attachment_names().end(), name), attachment_names().end());
80  attachments().erase(name);
81  const char* typeName = attachment_info_traits<TAttachment>::type_name();
82  attachment_types().erase(typeName);
83  }
84 
85  static void declare_attachment (const std::string& name,
86  const std::string& typeName,
87  bool passOnBehaviour = false)
88  {
89  UG_COND_THROW(attachment_types()[typeName].declareFunc == 0,
90  "Unregistered attachment type used in "
91  << "GlobalAttachments::declare_attachment: '"
92  << typeName << "' during declaration of attachment '"
93  << name << "'.");
94  attachment_types()[typeName].declareFunc(name, passOnBehaviour);
95  }
96 
97  template <class TAttachment>
98  static void register_attachment_type ()
99  {
100  std::string typeName = attachment_info_traits<TAttachment>::type_name();
102  }
103 
104  static const std::vector<std::string>&
106  {
107  return attachment_names();
108  }
109 
110  static
111  bool is_declared(const std::string& name)
112  {
113  return attachments().find(name) != attachments().end();
114  }
115 
116  static
117  bool attachment_pass_on_behaviour(const std::string& name)
118  {
119  UG_COND_THROW(!is_declared(name), "Undeclared attachment queried: " << name);
120  return attachments()[name].attachment->default_pass_on_behaviour();
121  }
122 
123  static
124  bool type_is_registered(const std::string& typeName)
125  {
126  return attachment_types().find(typeName) != attachment_types().end();
127  }
128 
129  #ifdef UG_PARALLEL
130  static void SynchronizeDeclaredGlobalAttachments(Grid& grid, int procId)
131  {
132  if (procId < 0) return; // this is not a parallel run
133 
134  //declare global attachments on all processors
135  pcl::ProcessCommunicator procComm;
136  std::vector<std::string> possible_attachment_names = GlobalAttachments::declared_attachment_names();
137  // only master proc loaded the grid
138  if (procId == 0)
139  procComm.broadcast<std::vector<std::string> >(possible_attachment_names, procId);
140  else
141  UG_THROW("There are more than one proc loading the grid"<<
142  "please make sure all processes broadcast their GlobalAttachments");
143 
144  std::vector<byte> locDeclared(possible_attachment_names.size(), 0);
145  std::vector<byte> globDeclared(possible_attachment_names.size(), 0);
146  // record local info
147  for(size_t i = 0; i < possible_attachment_names.size(); ++i){
148  byte& b = locDeclared[i];
149  if(GlobalAttachments::is_declared(possible_attachment_names[i])){
150  b |= 1;
151  if(GlobalAttachments::is_attached<Vertex>(grid, possible_attachment_names[i]))
152  b |= 1<<1;
153  if(GlobalAttachments::is_attached<Edge>(grid, possible_attachment_names[i]))
154  b |= 1<<2;
155  if(GlobalAttachments::is_attached<Face>(grid, possible_attachment_names[i]))
156  b |= 1<<3;
157  if(GlobalAttachments::is_attached<Volume>(grid, possible_attachment_names[i]))
158  b |= 1<<4;
159  }
160  }
161  // sum up all the local to the global
162  procComm.allreduce(locDeclared, globDeclared, PCL_RO_BOR);
163  // update the local with the global
164  for(size_t i = 0; i < possible_attachment_names.size(); ++i){
165  byte& b = globDeclared[i];
166  if(b & 1){
167  if(!GlobalAttachments::is_declared(possible_attachment_names[i]))
168  GlobalAttachments::declare_attachment(possible_attachment_names[i], "double", true);
169  if(b & 1<<1)
170  GlobalAttachments::attach<Vertex>(grid, possible_attachment_names[i]);
171  if(b & 1<<2)
172  GlobalAttachments::attach<Edge>(grid, possible_attachment_names[i]);
173  if(b & 1<<3)
174  GlobalAttachments::attach<Face>(grid, possible_attachment_names[i]);
175  if(b & 1<<4)
176  GlobalAttachments::attach<Volume>(grid, possible_attachment_names[i]);
177  }
178  }
179 
180  }
181  #endif
182 
183  template <class TElem>
184  static
185  void attach(Grid& g, const std::string& name)
186  {
188  IFunctionEntry& fe = function_entry<TElem>(ae);
189  fe.attach(g, *ae.attachment);
190  }
191 
192  template <class TElem>
193  static
194  bool is_attached(Grid& g, const std::string& name)
195  {
197  return g.has_attachment<TElem>(*ae.attachment);
198  }
199 
200  template <class TAttachment>
201  static
202  TAttachment attachment (const std::string& name)
203  {
205  TAttachment* a = dynamic_cast<TAttachment*>(e.attachment);
206  UG_COND_THROW(!a, "Attachment with invalid type queried. Given type "
207  "is " << e.type << ", queried type is " <<
209  return *a;
210  }
211 
212  static
213  const char* type_name (const std::string& name)
214  {
216  return e.type;
217  }
218 
219  template <class TElem>
220  static
221  void read_attachment_values (std::istream& in,
222  Grid& grid,
223  const std::string& name)
224  {
226  IFunctionEntry& fe = function_entry<TElem>(ae);
227  fe.readFunc(in, grid, *ae.attachment);
228  }
229 
230 
231  template <class TElem>
232  static
233  void write_attachment_values (std::ostream& out,
234  Grid& grid,
235  const std::string& name)
236  {
238  function_entry<TElem>(ae).writeFunc(out, grid, *ae.attachment);
239  }
240 
241  template <class TElem>
242  static
244  Grid& grid,
245  const std::string& name)
246  {
248  IFunctionEntry& fe = function_entry<TElem>(ae);
249  fe.addSerializer(handler, grid, *ae.attachment);
250  }
251 
252 
253  private:
255  // TYPES
258  AttachmentEntry (IAttachment* a, const char* t, int fi) :
259  attachment(a), type(t), functionIndex(fi) {}
261  const char* type;
263  };
264 
265  struct IFunctionEntry {
267  void (*readFunc ) (std::istream&, Grid&, IAttachment&);
268  void (*writeFunc) (std::ostream&, Grid&, IAttachment&);
270  void (*attach) (Grid&, IAttachment&);
271  };
272 
273  template <class TElem, class TAttachment>
274  struct FunctionEntry : public IFunctionEntry {
276  readFunc = &read_attachment_from_stream<TElem, TAttachment>;
277  writeFunc = &write_attachment_to_stream<TElem, TAttachment>;
278  addSerializer = &add_attachment_serializer<TElem, TAttachment>;
279  attach = &cast_and_attach<TElem, TAttachment>;
280  }
281  };
282 
285  void (*declareFunc) (const std::string&, bool);
286  };
287 
288  template <class TAttachment>
289  struct AttachmentType : public IAttachmentType {
291  declareFunc = &declare_attachment<TAttachment>;
292  }
293  };
294 
295 
296  typedef std::map<std::string, AttachmentEntry> AttachmentMap;
297  typedef std::map<std::string, IAttachmentType> AttachmentTypeMap;
298  typedef std::vector<IFunctionEntry> FunctionVec;
299 
300 
302  // METHODS
303  static
305  {
306  static GlobalAttachments h;
307  return h;
308  }
309 
311 
313  {
314  AttachmentMap& m = attachments();
315  for(AttachmentMap::iterator i = m.begin(); i != m.end(); ++i) {
316  if(i->second.attachment)
317  delete i->second.attachment;
318  }
319  }
320 
321  static
322  std::vector<std::string>& attachment_names() {
323  return inst().m_attachmentNames;
324  }
325 
326  static
328  return inst().m_attachmentMap;
329  }
330 
331  static
333  static bool initialized = false;
334  if(!initialized){
335  initialized = true;
337  }
338  return inst().m_attachmentTypeMap;
339  }
340 
341  template <class TElem>
342  static
344  return inst().m_functionVecs[TElem::BASE_OBJECT_ID];
345  }
346 
347  static
348  AttachmentEntry& attachment_entry(const std::string& name)
349  {
351  UG_COND_THROW(!e.attachment, "Undeclared attachment queried: " << name);
352  return e;
353  }
354 
355  template <class TElem>
356  static
357  IFunctionEntry& function_entry(const std::string& name)
358  {
359  return function_entry<TElem>(attachment_entry(name));
360  }
361 
362  template <class TElem>
363  static
365  {
366  return functions<TElem>().at(ae.functionIndex);
367  }
368 
369  template <class TElem>
370  static
372  functions<TElem>().erase(functions<TElem>().begin() + ae.functionIndex);
373  }
374 
375  template <class TElem, class TAttachment>
376  static
378  std::istream& in,
379  Grid& grid,
381  {
382  TAttachment& a = dynamic_cast<TAttachment&>(attachment);
383 
384  if(!grid.has_attachment<TElem>(a))
385  grid.attach_to<TElem>(a);
386 
388 
389  for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
390  iter != grid.end<TElem>(); ++iter)
391  {
393  UG_COND_THROW(!in, "Failed to read attachment entry.\n");
394  }
395  }
396 
397 
398  template <class TElem, class TAttachment>
399  static
401  std::ostream& out,
402  Grid& grid,
404  {
405  TAttachment& a = dynamic_cast<TAttachment&>(attachment);
406 
407  if(!grid.has_attachment<TElem>(a))
408  return;
409 
411 
412  const typename Grid::traits<TElem>::iterator iterEnd = grid.end<TElem>();
413  for(typename Grid::traits<TElem>::iterator iter = grid.begin<TElem>();
414  iter != iterEnd;)
415  {
417  UG_COND_THROW(!out, "Failed to write attachment entry.\n");
418  ++iter;
419  if(iter != iterEnd)
420  out << " ";
421  }
422  }
423 
424  template <class TElem, class TAttachment>
425  static
426  void//SmartPtr<GeomObjDataSerializer<TElem> >
429  Grid& g,
431  {
432  TAttachment& a = dynamic_cast<TAttachment&>(attachment);
434  create(g, a));
435  }
436 
437  template <class TElem, class TAttachment>
438  static
440  Grid& grid,
442  {
443  TAttachment& a = dynamic_cast<TAttachment&>(attachment);
444 
445  if(!grid.has_attachment<TElem>(a))
446  grid.attach_to<TElem>(a);
447  }
448 
449  static
451  {
452  //todo: explicit registration of common types in
453  // GlobalAttachments itself isn't really the best way to go
454  // (e.g. requires inclusion of 'ugmath_types.h').
455  register_attachment_type<Attachment<bool> >();
456  register_attachment_type<Attachment<char> >();
457  register_attachment_type<Attachment<byte> >();
458  register_attachment_type<Attachment<int> >();
459  register_attachment_type<Attachment<uint> >();
460  register_attachment_type<Attachment<float> >();
461  register_attachment_type<Attachment<double> >();
462 
463  register_attachment_type<Attachment<vector1> >();
464  register_attachment_type<Attachment<vector2> >();
465  register_attachment_type<Attachment<vector3> >();
466  register_attachment_type<Attachment<vector4> >();
467  }
469  // VARIABLES
470  std::vector<std::string> m_attachmentNames;
474 };
475 
476 }// end of namespace
477 
478 #endif //__H__UG_global_attachments
location name
Definition: checkpoint_util.lua:128
Definition: pcl_process_communicator.h:70
void allreduce(const void *sendBuf, void *recBuf, int count, DataType type, ReduceOperation op) const
performs MPI_Allreduce on the processes of the communicator.
Definition: pcl_process_communicator.cpp:318
void broadcast(void *v, size_t size, DataType type, int root=0) const
Definition: pcl_process_communicator.cpp:685
Serialization callback for grid attachments.
Definition: serialization.h:290
Global attachments are automatically read/written from/to files and are considered during redistribut...
Definition: global_attachments.h:44
static void write_attachment_to_stream(std::ostream &out, Grid &grid, IAttachment &attachment)
Definition: global_attachments.h:400
static bool is_attached(Grid &g, const std::string &name)
Definition: global_attachments.h:194
static void SynchronizeDeclaredGlobalAttachments(Grid &grid, int procId)
Definition: global_attachments.h:130
static FunctionVec & functions()
Definition: global_attachments.h:343
~GlobalAttachments()
Definition: global_attachments.h:312
static AttachmentTypeMap & attachment_types()
Definition: global_attachments.h:332
static const std::vector< std::string > & declared_attachment_names()
Definition: global_attachments.h:105
std::map< std::string, IAttachmentType > AttachmentTypeMap
Definition: global_attachments.h:297
FunctionVec m_functionVecs[4]
Definition: global_attachments.h:473
static GlobalAttachments & inst()
Definition: global_attachments.h:304
static void undeclare_attachment(const std::string &name)
Definition: global_attachments.h:72
static void write_attachment_values(std::ostream &out, Grid &grid, const std::string &name)
Definition: global_attachments.h:233
static std::vector< std::string > & attachment_names()
Definition: global_attachments.h:322
static void attach(Grid &g, const std::string &name)
Definition: global_attachments.h:185
static void register_standard_attachment_types()
Definition: global_attachments.h:450
static AttachmentEntry & attachment_entry(const std::string &name)
Definition: global_attachments.h:348
static void add_attachment_serializer(GridDataSerializationHandler &handler, Grid &g, IAttachment &attachment)
Definition: global_attachments.h:427
std::vector< std::string > m_attachmentNames
Definition: global_attachments.h:470
static bool type_is_registered(const std::string &typeName)
Definition: global_attachments.h:124
static bool attachment_pass_on_behaviour(const std::string &name)
Definition: global_attachments.h:117
static void read_attachment_from_stream(std::istream &in, Grid &grid, IAttachment &attachment)
Definition: global_attachments.h:377
static void read_attachment_values(std::istream &in, Grid &grid, const std::string &name)
Definition: global_attachments.h:221
static void declare_attachment(const std::string &name, bool passOnBehaviour=false)
Definition: global_attachments.h:47
static void add_data_serializer(GridDataSerializationHandler &handler, Grid &grid, const std::string &name)
Definition: global_attachments.h:243
static void register_attachment_type()
Definition: global_attachments.h:98
static void remove_function_entry(const AttachmentEntry &ae)
Definition: global_attachments.h:371
GlobalAttachments()
Definition: global_attachments.h:310
static void declare_attachment(const std::string &name, const std::string &typeName, bool passOnBehaviour=false)
Definition: global_attachments.h:85
std::map< std::string, AttachmentEntry > AttachmentMap
Definition: global_attachments.h:296
static void cast_and_attach(Grid &grid, IAttachment &attachment)
Definition: global_attachments.h:439
std::vector< IFunctionEntry > FunctionVec
Definition: global_attachments.h:298
AttachmentMap m_attachmentMap
Definition: global_attachments.h:471
static IFunctionEntry & function_entry(const AttachmentEntry &ae)
Definition: global_attachments.h:364
static TAttachment attachment(const std::string &name)
Definition: global_attachments.h:202
static bool is_declared(const std::string &name)
Definition: global_attachments.h:111
static const char * type_name(const std::string &name)
Definition: global_attachments.h:213
AttachmentTypeMap m_attachmentTypeMap
Definition: global_attachments.h:472
static AttachmentMap & attachments()
Definition: global_attachments.h:327
static IFunctionEntry & function_entry(const std::string &name)
Definition: global_attachments.h:357
the generic attachment-accessor for access to grids attachment pipes.
Definition: grid.h:182
Serialization of data associated with grid elements.
Definition: serialization.h:186
void add(SPVertexDataSerializer cb)
Adds a callback class for serialization and deserialization.
Definition: serialization.cpp:69
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
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
geometry_traits< TGeomObj >::iterator begin()
Definition: grid_impl.hpp:164
geometry_traits< TGeomObj >::iterator end()
Definition: grid_impl.hpp:175
the interface for attachments.
Definition: attachment_pipe.h:239
#define PCL_RO_BOR
Definition: pcl_methods.h:68
#define UG_THROW(msg)
Definition: error.h:57
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
function util LuaCallbackHelper create(func)
the ug namespace
Definition: global_attachments.h:256
const char * type
Definition: global_attachments.h:261
int functionIndex
Definition: global_attachments.h:262
AttachmentEntry()
Definition: global_attachments.h:257
IAttachment * attachment
Definition: global_attachments.h:260
AttachmentEntry(IAttachment *a, const char *t, int fi)
Definition: global_attachments.h:258
Definition: global_attachments.h:289
AttachmentType()
Definition: global_attachments.h:290
Definition: global_attachments.h:274
FunctionEntry()
Definition: global_attachments.h:275
Definition: global_attachments.h:283
void(* declareFunc)(const std::string &, bool)
Definition: global_attachments.h:285
IAttachmentType()
Definition: global_attachments.h:284
Definition: global_attachments.h:265
void(* writeFunc)(std::ostream &, Grid &, IAttachment &)
Definition: global_attachments.h:268
void(* readFunc)(std::istream &, Grid &, IAttachment &)
Definition: global_attachments.h:267
void(* addSerializer)(GridDataSerializationHandler &, Grid &, IAttachment &)
Definition: global_attachments.h:269
void(* attach)(Grid &, IAttachment &)
Definition: global_attachments.h:270
IFunctionEntry()
Definition: global_attachments.h:266
geometry_traits< TElem >::iterator iterator
Definition: grid.h:143
Definition: attachment_info_traits.h:46
static const char * type_name()
static void write_value(std::ostream &out, const_reference_type v)
Definition: attachment_io_traits.h:45
static void read_value(std::istream &in, reference_type v)
Definition: attachment_io_traits.h:46