ug4
deg_layer_mngr_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015: G-CSC, Goethe University Frankfurt
3  * Author: Dmitry Logashenko
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 /*
34  * Implementation of the degenerated layer subset manager.
35  */
36 // ug4 headers
38 
39 namespace ug {
40 
46 template <int dim>
48 (
50 )
51 : m_spSH (spSH), m_bClosed (false)
52 {
53 // Check the subset handler:
54  if (m_spSH.invalid ())
55  UG_THROW ("DegeneratedLayerManager: Invalid subset handler specified!");
56 
57 // Initialize the data:
59 
60 // Initialize the attachment:
61  MultiGrid * pMG = (MultiGrid *) (m_spSH->multi_grid ());
62  pMG->template attach_to_dv<Vertex> (m_aVertexMarks, D_LAYER_UNKNOWN);
63  m_aaVertMarks.access (*pMG, m_aVertexMarks);
64 
65 // Register the callbacks in the message hub:
67  pMG->message_hub()->register_class_callback
70  pMG->message_hub()->register_class_callback
72 }
73 
77 template <int dim>
79 {
80  MultiGrid * pMG = (MultiGrid *) (m_spSH->multi_grid ());
81  m_aaVertMarks.invalidate ();
82  pMG->template detach_from<Vertex> (m_aVertexMarks);
83  m_bClosed = false; // (to be on the very safe side...)
84 }
85 
89 template <int dim>
91 (
92  const char * ss_names
93 )
94 {
95  if (m_bClosed)
96  UG_LOG ("DegeneratedLayerManager: Adding subsets to a closed manager.");
97 
98 // If extended - then not closed any more
99  m_bClosed = false;
100 
101 // Parse the subset names:
102  std::vector<std::string> vssNames;
103  TokenizeString (ss_names, vssNames);
104 
105 // Add the subsets to the group:
106  m_layerSsGrp.add (vssNames);
107 }
108 
112 template <int dim>
114 (
115  const char * ss_names
116 )
117 {
118 // If extended - then not closed any more
119  m_bClosed = false;
120 
121 // Parse the subset names:
122  std::vector<std::string> vssNames;
123  TokenizeString (ss_names, vssNames);
124 
125 // Add the subsets to the group:
126  m_layerSsGrp.remove (vssNames);
127 }
128 
132 template <int dim>
134 {
135  size_t init_n_subsets = m_layerSsGrp.size ();
136 
137 // Check the dimensionality of the subsets:
138  size_t i = 0;
139  while (i < m_layerSsGrp.size ())
140  if (DimensionOfSubset (*m_spSH, m_layerSsGrp [i]) != dim)
141  {
142  UG_LOG ("DegeneratedLayerManager: Low-dimensional subset '"
143  << m_spSH->get_subset_name (m_layerSsGrp [i])
144  << "' specified as a degenerated layer. Removed from the list.\n");
145  m_layerSsGrp.remove (m_layerSsGrp [i]);
146  i = 0;
147  }
148  else i++;
149 
150 // Check if all the subsets are removed due to the illegal dimensionality
151  if (init_n_subsets != 0 && m_layerSsGrp.size () == 0)
152  UG_THROW ("DegeneratedLayerManager: All the specified subsets have illegal dimensionality!\n");
153 
154 // Mark the vertices:
155  mark_vertices ();
156 
157 // Done:
158  m_bClosed = true;
159 }
160 
164 template <int dim>
166 (
168  bool as_low_dim
169 )
170 {
171  if (! is_closed ())
172  UG_THROW ("DegeneratedLayerManager: The manager must be closed before use.");
173  for (size_t i = 0; i < m_layerSsGrp.size (); i++)
174  refiner->mark_as_fracture (m_layerSsGrp[i], as_low_dim);
175 }
176 
183 template <int dim>
185 {
186  typedef typename geometry_traits<element_type>::const_iterator t_elem_iter;
187 
188  MultiGrid * pMG = (MultiGrid *) (m_spSH->multi_grid ());
189 
190 // Mark all vertices of the fracture elements:
191  for (size_t i = 0; i < m_layerSsGrp.size (); i++)
192  {
193  int si = m_layerSsGrp [i];
194  for (size_t lev = 0; lev < pMG->num_levels (); lev++)
195  {
196  t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
197  for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
198  iElem != list_end; ++iElem)
199  {
200  element_type * elem = *iElem;
201  for (size_t i = 0; i < elem->num_vertices (); i++)
202  {
203  Vertex * vert = elem->vertex(i);
204  m_aaVertMarks [vert] = (! vert->is_constrained ())? D_LAYER_INNER : D_LAYER_OUTER;
205  // REMARK: Constrained vertices cannot be inner for degenerated layers!
206  // We cannot catch this situation somewhere else, so we do it here.
207  }
208  }
209  }
210  }
211 
212 // Unmark all vertices in the other (not-degenerated-layer) elements:
213  for (int si = 0; si < m_spSH->num_subsets (); si++)
214  if (DimensionOfSubset (*m_spSH, si) == dim && ! m_layerSsGrp.contains (si))
215  for (size_t lev = 0; lev < pMG->num_levels (); lev++)
216  {
217  t_elem_iter list_end = m_spSH->template end<element_type> (si, lev);
218  for (t_elem_iter iElem = m_spSH->template begin<element_type> (si, lev);
219  iElem != list_end; ++iElem)
220  {
221  element_type * elem = *iElem;
222  for (size_t i = 0; i < elem->num_vertices (); i++)
223  m_aaVertMarks [elem->vertex(i)] = D_LAYER_OUTER;
224  }
225  }
226 
227 #ifdef UG_PARALLEL
228 // Make the marking consistent
229  AttachmentAllReduce<Vertex> (*pMG, m_aVertexMarks, PCL_RO_MIN);
230 #endif // UG_PARALLEL
231 }
232 
236 template <int dim>
238 (
239  const GridMessage_Adaption & msg
240 )
241 {
242  if (m_bClosed && msg.adaption_ends ())
243  mark_vertices ();
244 }
245 
249 template <int dim>
251 (
252  const GridMessage_Distribution & msg
253 )
254 {
255  if (m_bClosed && msg.msg () == GMDT_DISTRIBUTION_STOPS)
256  mark_vertices ();
257 }
258 
264 template <int dim>
266 (
267  element_type * elem,
268  size_t & num_side_co,
269  side_type * & inner_side,
270  size_t & inner_side_idx,
271  size_t inner_side_corners [],
272  side_type * & outer_side,
273  size_t & outer_side_idx,
274  size_t outer_side_corners [],
275  size_t ass_co []
276 )
277 {
278  size_t n_inner, n_outer;
279  size_t n_co = elem->num_vertices ();
280  MultiGrid * pMG = (MultiGrid *) (m_spSH->multi_grid ());
281  typename Grid::traits<Edge>::secure_container edge_list;
282 
283 // First, we check, whether the inner and outer sides are well defined.
284 // Loop over the sides: We look for sides with only inner or only outer corners
285  inner_side = NULL; n_inner = 0;
286  outer_side = NULL; n_outer = 0;
287  for (size_t i = 0; i < elem->num_sides (); i++)
288  {
289  side_type * side = pMG->get_side (elem, i);
290  bool has_inner = false, has_outer = false;
291  size_t side_n_co = side->num_vertices ();
292  for (size_t co = 0; co < side_n_co; co++)
293  {
294  int mark = vert_mark (side->vertex (co));
295  if (mark == D_LAYER_OUTER)
296  has_outer = true;
297  else if (mark == D_LAYER_INNER)
298  has_inner = true;
299  else
300  UG_THROW ("DegeneratedLayerManager: Some vertices are not marked!");
301  }
302 
303  if (has_inner && has_outer) continue; // this is a 'degenerated' side
304 
305  if (has_inner)
306  { // this is the inner side
307  if (inner_side != NULL)
308  UG_THROW ("DegeneratedLayerManager: Two inner sides of a degenerated layer element found!");
309  inner_side = side;
310  inner_side_idx = i;
311  n_inner = side_n_co;
312  }
313  else
314  { // this is the outer side
315  if (outer_side != NULL)
316  UG_THROW ("DegeneratedLayerManager: Two outer sides of a degenerated layer element found!");
317  outer_side = side;
318  outer_side_idx = i;
319  n_outer = side_n_co;
320  }
321  }
322  if (n_inner != n_outer || 2 * n_inner != n_co)
323  UG_THROW ("DegeneratedLayerManager: Unrecognized degenerated layer element!");
324  num_side_co = n_inner;
325 
326 // Now: Corner of inner side are exactly those marked as inner, and the same for the outer side
327  Vertex * inner_vert_ptr [maxLayerSideCorners], * outer_vert_ptr [maxLayerSideCorners];
328  size_t inner_corners [maxLayerSideCorners], outer_corners [maxLayerSideCorners];
329  size_t inner_i = 0, outer_i = 0;
330  for (size_t co = 0; co < n_co; co++)
331  {
332  Vertex * vrt = elem->vertex (co);
333  if (vert_mark (vrt) == D_LAYER_INNER)
334  {
335  inner_vert_ptr [inner_i] = vrt;
336  inner_corners [inner_i] = co;
337  inner_i++;
338  }
339  else
340  {
341  outer_vert_ptr [outer_i] = vrt;
342  outer_corners [outer_i] = co;
343  outer_i++;
344  }
345  }
346  if (inner_i != n_inner || outer_i != n_outer)
347  UG_THROW ("DegeneratedLayerManager: Failed to get the vertex-side correspondence!");
348 
349 // Order the corner indices according to the corners of the sides
350  for (size_t i = 0; i < n_inner; i++)
351  {
352  size_t co;
353 
354  co = 0;
355  while (inner_side->vertex (co) != inner_vert_ptr [i])
356  if (++co == n_inner)
357  UG_THROW ("DegeneratedLayerManager: Failed! Missing inner vertex?");
358  inner_side_corners [co] = inner_corners [i];
359 
360  co = 0;
361  while (outer_side->vertex (co) != outer_vert_ptr [i])
362  if (++co == n_outer)
363  UG_THROW ("DegeneratedLayerManager: Failed! Missing outer vertex?");
364  outer_side_corners [co] = outer_corners [i];
365  }
366 
367 // Loop over the edges: Find out the associated corners
368  if (ass_co != NULL)
369  {
370  pMG->associated_elements (edge_list, elem);
371  for (size_t i = 0; i < edge_list.size (); i++)
372  {
373  Edge * e = edge_list [i];
374  Vertex * v_1 = e->vertex (0); int mark_1 = vert_mark (v_1);
375  Vertex * v_2 = e->vertex (1); int mark_2 = vert_mark (v_2);
376  Vertex * t;
377  size_t co_1, co_2;
378 
379  if (mark_1 == mark_2)
380  continue; // an edge of the inner or the outer size
381 
382  if (mark_1 == D_LAYER_OUTER)
383  { // Vertex # 1 must be inner, vertex # 2 must be outer
384  t = v_1; v_1 = v_2; v_2 = t;
385  }
386 
387  co_1 = 0;
388  while (inner_vert_ptr[co_1] != v_1)
389  if (++co_1 == n_inner)
390  UG_THROW ("DegeneratedLayerManager: Cannot find an inner node by vertex!");
391 
392  co_2 = 0;
393  while (outer_vert_ptr[co_2] != v_2)
394  if (++co_2 == n_outer)
395  UG_THROW ("DegeneratedLayerManager: Cannot find an outer node by vertex!");
396 
397  ass_co [inner_corners [co_1]] = outer_corners [co_2];
398  ass_co [outer_corners [co_2]] = inner_corners [co_1];
399  }
400  }
401 }
402 
409 template <int dim>
411 (
412  int layer_si,
413  int middle_si
414 )
415 {
416  typedef typename geometry_traits<element_type>::const_iterator t_elem_iter;
417 
418  MultiGrid * pMG = (MultiGrid *) (m_spSH->multi_grid ());
419 
420 // Assign the default value of the subset (if necessary)
421  if (middle_si < 0) middle_si = m_spSH->num_subsets ();
422 
423 // Loop the elements of the layer in all the grid levels
425  for (size_t lev = 0; lev < pMG->num_levels (); lev++)
426  {
427  t_elem_iter list_end = m_spSH->template end<element_type> (layer_si, lev);
428  for (t_elem_iter iElem = m_spSH->template begin<element_type> (layer_si, lev);
429  iElem != list_end; ++iElem)
430  {
431  element_type * elem = *iElem;
432  size_t num_side_co;
433  side_type * inner_side, * outer_side;
434  size_t inner_side_idx, outer_side_idx;
435  size_t inner_side_corners [maxLayerSideCorners], outer_side_corners [maxLayerSideCorners];
436 
437  // get the inner side
438  get_layer_sides (elem, num_side_co,
439  inner_side, inner_side_idx, inner_side_corners,
440  outer_side, outer_side_idx, outer_side_corners);
441 
442  // assign the subset
443  m_spSH->assign_subset (inner_side, middle_si);
444  }
445  }
447 
448  return middle_si;
449 }
450 
456 template <int dim>
458 (
459  int layer_si,
460  const char* middle_ss_name
461 )
462 {
463 // Look for the subset to assign
464  int middle_si = -1;
465  bool new_ss = true;
466  for (int si = 0; si < m_spSH->num_subsets (); si++)
467  if (strcmp (middle_ss_name, m_spSH->get_subset_name (si)) == 0)
468  {
469  middle_si = si;
470  new_ss = false;
471  break;
472  }
473 
474 // Assign the subset
475  middle_si = assign_middle_subset (layer_si, middle_si);
476 
477 // Set the name
478  if (new_ss)
479  m_spSH->set_subset_name (middle_ss_name, middle_si);
480 
481  return middle_si;
482 }
483 
489 template <int dim>
491 (
492  const char* layer_ss_name,
493  const char* middle_ss_name
494 )
495 {
496 // Look for the subset of the layer
497  for (int si = 0; si < m_spSH->num_subsets (); si++)
498  if (strcmp (layer_ss_name, m_spSH->get_subset_name (si)) == 0)
499  return assign_middle_subset (si, middle_ss_name);
500  UG_THROW ("DegeneratedLayerManager: Subset '" << layer_ss_name << "' not found");
501 }
502 
503 } // end namespace ug
504 
505 /* End of File */
Definition: smart_pointer.h:108
Gegenerated layer subset manager.
Definition: deg_layer_mngr.h:99
MultiGrid::AttachmentAccessor< Vertex, mark_attachment_type > m_aaVertMarks
Attachment accessor.
Definition: deg_layer_mngr.h:237
void close()
Closes the manager, i.e. computes all the data, ...
Definition: deg_layer_mngr_impl.h:133
MessageHub::SPCallbackId m_spGridDistributionCallbackID
Definition: deg_layer_mngr.h:244
void grid_distribution_callback(const GridMessage_Distribution &msg)
Called when a grid has been distributed between different processes.
Definition: deg_layer_mngr_impl.h:251
void remove(const char *ss_names)
Removes a fracture subdomain (e.g. for dimension-adaptive method)
Definition: deg_layer_mngr_impl.h:114
SubsetGroup m_layerSsGrp
Subset group of the fractures.
Definition: deg_layer_mngr.h:232
MessageHub::SPCallbackId m_spGridAdaptionCallbackID
Definition: deg_layer_mngr.h:243
virtual ~DegeneratedLayerManager()
Destructor.
Definition: deg_layer_mngr_impl.h:78
@ D_LAYER_UNKNOWN
Definition: deg_layer_mngr.h:119
void grid_adaption_callback(const GridMessage_Adaption &msg)
Called when a grid adaption has been performed.
Definition: deg_layer_mngr_impl.h:238
void add(const char *ss_names)
Adds a fracture subdomain.
Definition: deg_layer_mngr_impl.h:91
grid_dim_traits< dim >::grid_base_object element_type
base grid element object type
Definition: deg_layer_mngr.h:105
SmartPtr< MultiGridSubsetHandler > m_spSH
Subset handler to use.
Definition: deg_layer_mngr.h:229
DegeneratedLayerManager(SmartPtr< MultiGridSubsetHandler > spSH)
Constructor.
Definition: deg_layer_mngr_impl.h:48
int assign_middle_subset(int layer_si, int middle_si=-1)
Assigns a different subset index to the inner sides of a layer.
Definition: deg_layer_mngr_impl.h:411
void init_refiner(SmartPtr< GlobalFracturedMediaRefiner > refiner, bool as_low_dim)
Initializes a refiner with the fracture subsets.
Definition: deg_layer_mngr_impl.h:166
grid_dim_traits< dim >::side_type side_type
grid element's side base object type
Definition: deg_layer_mngr.h:108
void mark_vertices()
Marks the inner fracture vertices.
Definition: deg_layer_mngr_impl.h:184
mark_attachment_type m_aVertexMarks
Attachment keeping the grid object marks for the vertices.
Definition: deg_layer_mngr.h:235
void get_layer_sides(element_type *elem, size_t &num_fract_co, side_type *&inner_side, size_t &inner_side_idx, size_t inner_side_corners[], side_type *&outer_side, size_t &outer_side_idx, size_t outer_side_corners[], size_t ass_co[]=NULL)
Gets the inner and the outer fracture sides of an element.
Definition: deg_layer_mngr_impl.h:266
Base-class for edges.
Definition: grid_base_objects.h:397
virtual Vertex * vertex(size_t index) const
Definition: grid_base_objects.h:366
SPMessageHub message_hub()
gives access to the grid's message-hub
Definition: grid.h:945
Vertex::side * get_side(Vertex *obj, size_t side)
This method returns the i-th side of an Edge, Face or Volume.
Definition: grid.cpp:1170
void associated_elements(traits< Vertex >::secure_container &elemsOut, TElem *e)
Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut.
Definition: grid_impl.hpp:466
A message sent along with "GridRefinement" messages.
Definition: lib_grid_messages.h:91
bool adaption_ends() const
tells whether grid adaption has just been started or has been finished.
Definition: lib_grid_messages.cpp:44
Definition: lib_grid_messages.h:195
Definition: lib_grid_messages.h:166
GridMessageDistributionType msg() const
Definition: lib_grid_messages.h:174
virtual bool is_constrained() const
returns true if the object is constrained by other objects.
Definition: grid_base_objects.h:188
void post_message(const TMsg &msg)
Posts a message to all callbacks which are registered for the given message tpye.
Definition: message_hub_impl.hpp:67
Definition: multi_grid.h:72
size_t num_levels() const
number of levels
Definition: multi_grid.h:145
Container which holds an array of pointers.
Definition: pointer_const_array.h:84
size_t size() const
returns the size of the associated array.
Definition: pointer_const_array_impl.hpp:106
void set_subset_handler(ConstSmartPtr< ISubsetHandler > sh)
set an underlying subset handler
Definition: subset_group.h:69
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
Definition: grid_base_object_traits.h:68
#define PCL_RO_MIN
Definition: pcl_methods.h:62
static const int dim
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
the ug namespace
@ GMCT_CREATION_STOPS
Definition: lib_grid_messages.h:191
@ GMCT_CREATION_STARTS
Definition: lib_grid_messages.h:190
void TokenizeString(const string &str, vector< string > &vToken, const char delimiter)
Definition: string_util.cpp:56
@ GMDT_DISTRIBUTION_STOPS
Definition: lib_grid_messages.h:162
int DimensionOfSubset(const ISubsetHandler &sh, int si)
returns the current dimension of the subset
Definition: subset_dim_util.cpp:89