Flow123d  intersections_paper-476-gbe68821
mesh.h
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file mesh.h
15  * @brief
16  */
17 
18 #ifndef MAKE_MESH_H
19 #define MAKE_MESH_H
20 
21 #include <vector>
22 #include <mpi.h>
23 
24 #include "mesh/mesh_types.hh"
25 
26 #include "mesh/nodes.hh"
27 //#include "mesh/elements.h"
28 //#include "mesh/sides.h"
29 #include "mesh/edges.h"
30 #include "mesh/neighbours.h"
31 #include "mesh/boundaries.h"
32 #include "mesh/partitioning.hh"
33 #include "mesh/region_set.hh"
34 #include "mesh/bounding_box.hh"
35 
38 #include "system/exceptions.hh"
39 
40 
41 
42 #define ELM 0
43 #define BC 1
44 #define NODE 2
45 
46 /**
47  * This parameter limits volume of elements from below.
48  */
49 #define MESH_CRITICAL_VOLUME 1.0E-12
50 
51 /**
52  * Provides for statement to iterate over the Nodes of the Mesh.
53  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
54  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
55  */
56 #define FOR_NODES(_mesh_, i) \
57  for( NodeFullIter i( (_mesh_)->node_vector.begin() ); \
58  i != (_mesh_)->node_vector.end(); \
59  ++i)
60 
61 /**
62  * Macro for conversion form Iter to FullIter for nodes.
63  */
64 #define NODE_FULL_ITER(_mesh_,i) \
65  (_mesh_)->node_vector.full_iter(i)
66 
67 /**
68  * Macro to get "NULL" ElementFullIter.
69  */
70 #define NODE_FULL_ITER_NULL(_mesh_) \
71  NodeFullIter((_mesh_)->node_vector)
72 
73 /**
74  * Macro for conversion form Iter to FullIter for elements.
75  */
76 #define ELEM_FULL_ITER(_mesh_,i) \
77  (_mesh_)->element.full_iter(i)
78 
79 
80 #define FOR_NODE_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements();(j)++)
81 #define FOR_NODE_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
82 
83 
85 public:
87 };
88 
89 
90 
91 //=============================================================================
92 // STRUCTURE OF THE MESH
93 //=============================================================================
94 
95 class Mesh {
96 public:
97  TYPEDEF_ERR_INFO( EI_ElemLast, int);
98  TYPEDEF_ERR_INFO( EI_ElemNew, int);
99  TYPEDEF_ERR_INFO( EI_RegLast, std::string);
100  TYPEDEF_ERR_INFO( EI_RegNew, std::string);
101  DECLARE_EXCEPTION(ExcDuplicateBoundary,
102  << "Duplicate boundary elements! \n"
103  << "Element id: " << EI_ElemLast::val << " on region name: " << EI_RegLast::val << "\n"
104  << "Element id: " << EI_ElemNew::val << " on region name: " << EI_RegNew::val << "\n");
105 
106 
107  /**
108  * \brief Types of search algorithm for finding intersection candidates.
109  */
110  typedef enum IntersectionSearch {
111  BIHsearch = 1,
112  BIHonly = 2,
113  BBsearch = 3
115 
116  /**
117  * \brief The definition of input record for selection of variant of file format
118  */
119  static const Input::Type::Selection & get_input_intersection_variant();
120 
121  static const unsigned int undef_idx=-1;
122  static const Input::Type::Record & get_input_type();
123 
124 
125 
126  /** Labels for coordinate indexes in arma::vec3 representing vectors and points.*/
127  enum {x_coord=0, y_coord=1, z_coord=2};
128 
129  /**
130  * Constructor from an input record.
131  * Do not process input record. That is done in init_from_input.
132  */
133  Mesh(Input::Record in_record, MPI_Comm com = MPI_COMM_WORLD);
134  /**
135  * Common part of both previous constructors and way how to reinitialize a mesh from the given input record.
136  */
137  void reinit(Input::Record in_record);
138 
139  /// Destructor.
140  ~Mesh();
141 
142  inline unsigned int n_nodes() const {
143  return node_vector.size();
144  }
145 
146  inline unsigned int n_elements() const {
147  return element.size();
148  }
149 
150  inline unsigned int n_boundaries() const {
151  return boundary_.size();
152  }
153 
154  inline unsigned int n_edges() const {
155  return edges.size();
156  }
157 
158  unsigned int n_corners();
159 
160  inline const RegionDB &region_db() const {
161  return region_db_;
162  }
163 
164  /**
165  * Returns pointer to partitioning object. Partitioning is created during setup_topology.
166  */
167  Partitioning *get_part();
168 
170  { return el_ds; }
171 
172  int *get_row_4_el() const
173  { return row_4_el; }
174 
175  int *get_el_4_loc() const
176  { return el_4_loc; }
177 
178  /**
179  * Returns MPI communicator of the mesh.
180  */
181  inline MPI_Comm get_comm() const { return comm_; }
182 
183 
184  MixedMeshIntersections &mixed_intersections();
185 
186  unsigned int n_sides();
187 
188  inline unsigned int n_vb_neighbours() const {
189  return vb_neighbours_.size();
190  }
191 
192  /**
193  * Returns maximal number of sides of one edge, which connects elements of dimension @p dim.
194  * @param dim Dimension of elements sharing the edge.
195  */
196  unsigned int max_edge_sides(unsigned int dim) const { return max_edge_sides_[dim-1]; }
197 
198  /**
199  * Reads mesh from stream.
200  *
201  * Method is especially used in unit tests.
202  */
203  void read_gmsh_from_stream(istream &in);
204  /**
205  * Reads input record, creates regions, read the mesh, setup topology. creates region sets.
206  */
207  void init_from_input();
208 
209 
210  /**
211  * Initialize all mesh structures from raw information about nodes and elements (including boundary elements).
212  * Namely: create remaining boundary elements and Boundary objects, find edges and compatible neighborings.
213  */
214  void setup_topology();
215 
216  /**
217  * Returns vector of ID numbers of elements, either bulk or bc elemnts.
218  */
219  vector<int> const & elements_id_maps( bool boundary_domain) const;
220 
221 
222  ElementAccessor<3> element_accessor(unsigned int idx, bool boundary=false);
223 
224  /**
225  * Reads elements and their affiliation to regions and region sets defined by user in input file
226  * Format of input record is defined in method RegionSetBase::get_input_type()
227  *
228  * @param region_list Array input AbstractRecords which define regions, region sets and elements
229  */
230  void read_regions_from_input(Input::Array region_list);
231 
232  /// Vector of nodes of the mesh.
234  /// Vector of elements of the mesh.
236 
237  /// Vector of boundary sides where is prescribed boundary condition.
238  /// TODO: apply all boundary conditions in the main assembling cycle over elements and remove this Vector.
240  /// vector of boundary elements - should replace 'boundary'
241  /// TODO: put both bulk and bc elements (on zero level) to the same vector or make better map id->element for field inputs that use element IDs
242  /// the avoid usage of ElementVector etc.
244 
245  /// Vector of MH edges, this should not be part of the geometrical mesh
247 
248  //flow::VectorId<int> bcd_group_id; // gives a index of group for an id
249 
250  /**
251  * Vector of individual intersections of two elements.
252  * This is enough for local mortar.
253  */
254  std::shared_ptr<MixedMeshIntersections> intersections;
255 
256  /**
257  * For every element El we have vector of indices into @var intersections array for every intersection in which El is master element.
258  * This is necessary for true mortar.
259  */
261 
262  /**
263  * Vector of compatible neighbourings.
264  */
266 
267  int n_insides; // # of internal sides
268  int n_exsides; // # of external sides
269  int n_sides_; // total number of sides (should be easy to count when we have separated dimensions
270 
271  int n_lines; // Number of line elements
272  int n_triangles; // Number of triangle elements
273  int n_tetrahedras; // Number of tetrahedra elements
274 
275  // Temporary solution for numbering of nodes on sides.
276  // The data are defined in RefElement<dim>::side_nodes,
277  // Mesh::side_nodes can be removed as soon as Element
278  // is templated by dimension.
279  //
280  // for every side dimension D = 0 .. 2
281  // for every element side 0 .. D+1
282  // for every side node 0 .. D
283  // index into element node array
285 
286  /**
287  * Check usage of regions, set regions to elements defined by user, close RegionDB
288  */
289  void check_and_finish();
290 
291  /// Precompute element bounding boxes if it is not done yet.
292  void compute_element_boxes();
293 
294  /// Return the mesh bounding box. Is set after call compute_element_boxes().
296  return mesh_box_;
297  }
298 
299  /// Getter for BIH. Creates and compute BIH at first call.
300  const BIHTree &get_bih_tree();\
301 
302  /// Getter for input type selection for intersection search algorithm.
303  IntersectionSearch get_intersection_search();
304 
305  // For each node the vector contains a list of elements that use this node
307 
308  /// Maximal distance of observe point from Mesh relative to its size
309  double global_observe_radius() const;
310 
311 
312 protected:
313 
314  /**
315  * This replaces read_neighbours() in order to avoid using NGH preprocessor.
316  *
317  * TODO:
318  * - Avoid maps:
319  *
320  * 4) replace EdgeVector by std::vector<Edge> (need not to know the size)
321  *
322  * 5) need not to have temporary array for Edges, only postpone setting pointers in elements and set them
323  * after edges are found; we can temporary save Edge index instead of pointer in Neigbours and elements
324  *
325  * 6) Try replace Edge * by indexes in Neigbours and elements (anyway we have mesh pointer in elements so it is accessible also from Neigbours)
326  *
327  */
328  void make_neighbours_and_edges();
329 
330  /**
331  * On edges sharing sides of many elements it may happen that each side has its nodes ordered in a different way.
332  * This method finds the permutation for each side so as to obtain the ordering of side 0.
333  */
334  void make_edge_permutations();
335  /**
336  * Create element lists for nodes in Mesh::nodes_elements.
337  */
338  void create_node_element_lists();
339  /**
340  * Find intersection of element lists given by Mesh::node_elements for elements givne by @p nodes_list parameter.
341  * The result is placed into vector @p intersection_element_list. If the @p node_list is empty, and empty intersection is
342  * returned.
343  */
344  void intersect_element_lists(vector<unsigned int> const &nodes_list, vector<unsigned int> &intersection_element_list);
345  /**
346  * Remove elements with dimension not equal to @p dim from @p element_list. Index of the first element of dimension @p dim-1,
347  * is returned in @p element_idx. If no such element is found the method returns false, if one such element is found the method returns true,
348  * if more elements are found we report an user input error.
349  */
350  bool find_lower_dim_element(ElementVector&elements, vector<unsigned int> &element_list, unsigned int dim, unsigned int &element_idx);
351 
352  /**
353  * Returns true if side @p si has same nodes as in the list @p side_nodes.
354  */
355  bool same_sides(const SideIter &si, vector<unsigned int> &side_nodes);
356 
357 
358  void element_to_neigh_vb();
359 
360  void count_element_types();
361  void count_side_types();
362 
363  /**
364  * Possibly modify region id of elements sets by user in "regions" part of input file.
365  *
366  * TODO: This method needs check in issue 'Review mesh setting'.
367  * Changes have been done during generalized region key and may be causing problems
368  * during the further development.
369  */
370  void modify_element_ids(const RegionDB::MapElementIDToRegionID &map);
371 
372  unsigned int n_bb_neigh, n_vb_neigh;
373 
374  /// Vector of both bulk and boundary IDs. Bulk elements come first, then boundary elements, but only the portion that appears
375  /// in input mesh file and has ID assigned.
376  ///
377  /// TODO: Rather should be part of GMSH reader, but in such case we need store pointer to it in the mesh (good idea, but need more general interface for readers)
378  mutable vector<int> bulk_elements_id_, boundary_elements_id_;
379  /// Number of elements read from input.
380  unsigned int n_all_input_elements_;
381 
382  /// Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
383  unsigned int max_edge_sides_[3];
384 
385  /**
386  * Database of regions (both bulk and boundary) of the mesh. Regions are logical parts of the
387  * domain that allows setting of different data and boundary conditions on them.
388  */
390  /**
391  * Mesh partitioning. Created in setup_topology.
392  */
393  std::shared_ptr<Partitioning> part_;
394 
395  /// Auxiliary vector of mesh elements bounding boxes.
397 
398  /// Bounding box of whole mesh.
400 
401  /**
402  * BIH Tree for intersection and observe points lookup.
403  */
404  std::shared_ptr<BIHTree> bih_tree_;
405 
406 
407  /**
408  * Accessor to the input record for the mesh.
409  */
411 
412  /**
413  * MPI communicator used for partitioning and ...
414  */
416 
417  friend class GmshMeshReader;
418  friend class RegionSetBase;
419  friend class Element;
420  friend class BIHTree;
421 
422 
423 
424 private:
425 
426  /// Index set assigning to global element index the local index used in parallel vectors.
427  int *row_4_el;
428  /// Index set assigning to local element index its global index.
429  int *el_4_loc;
430  /// Parallel distribution of elements.
432 };
433 
434 
435 #include "mesh/side_impl.hh"
436 #include "mesh/element_impls.hh"
437 #include "mesh/neighbours_impl.hh"
438 
439 /**
440  * Provides for statement to iterate over the Elements of the Mesh.
441  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
442  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
443  */
444 #define FOR_ELEMENTS(_mesh_,__i) \
445  for( ElementFullIter __i( (_mesh_)->element.begin() ); \
446  __i != (_mesh_)->element.end(); \
447  ++__i)
448 
449 /**
450  * Macro for conversion form Iter to FullIter for elements.
451  */
452 #define ELEMENT_FULL_ITER(_mesh_,i) \
453  (_mesh_)->element.full_iter(i)
454 
455 /**
456  * Macro to get "NULL" ElementFullIter.
457  */
458 #define ELEMENT_FULL_ITER_NULL(_mesh_) \
459  ElementFullIter((_mesh_)->element)
460 
461 
462 #define FOR_BOUNDARIES(_mesh_,i) \
463 for( std::vector<Boundary>::iterator i= (_mesh_)->boundary_.begin(); \
464  i != (_mesh_)->boundary_.end(); \
465  ++i)
466 
467 /**
468  * Macro for conversion form Iter to FullIter for boundaries.
469  */
470 #define BOUNDARY_FULL_ITER(_mesh_,i) \
471  (_mesh_)->boundary.full_iter(i)
472 
473 /**
474  * Macro to get "NULL" BoundaryFullIter.
475  */
476 #define BOUNDARY_NULL(_mesh_) \
477  BoundaryFullIter((_mesh_)->boundary)
478 
479 
480 /**
481  * Provides for statement to iterate over the Edges of the Mesh. see FOR_ELEMENTS
482  */
483 #define FOR_EDGES(_mesh_,__i) \
484  for( vector<Edge>::iterator __i = (_mesh_)->edges.begin(); \
485  __i !=(_mesh_)->edges.end(); \
486  ++__i)
487 
488 #define FOR_SIDES(_mesh_, it) \
489  FOR_ELEMENTS((_mesh_), ele) \
490  for(SideIter it = ele->side(0); it->el_idx() < ele->n_sides(); ++it)
491 
492 #define FOR_SIDE_NODES(i,j) for((j)=0;(j)<(i)->n_nodes;(j)++)
493 
494 
495 #define FOR_NEIGHBOURS(_mesh_, it) \
496  for( std::vector<Neighbour>::iterator it = (_mesh_)->vb_neighbours_.begin(); \
497  (it)!= (_mesh_)->vb_neighbours_.end(); ++it)
498 
499 #define FOR_NEIGH_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements;(j)++)
500 #define FOR_NEIGH_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
501 
502 
503 #endif
504 //-----------------------------------------------------------------------------
505 // vim: set cindent:
int n_triangles
Definition: mesh.h:272
Distribution * el_ds
Parallel distribution of elements.
Definition: mesh.h:431
Class for the mesh partitioning. This should provide:
Definition: partitioning.hh:39
const BoundingBox & get_mesh_boungin_box()
Return the mesh bounding box. Is set after call compute_element_boxes().
Definition: mesh.h:295
Bounding box in 3d ambient space.
Definition: bounding_box.hh:45
vector< vector< unsigned int > > node_elements
Definition: mesh.h:306
Accessor to input data conforming to declared Array.
Definition: accessors.hh:561
int MPI_Comm
Definition: mpi.h:141
Nodes of a mesh.
static Input::Type::Record input_type
Definition: mesh.h:86
int n_lines
Definition: mesh.h:271
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:150
std::shared_ptr< MixedMeshIntersections > intersections
Definition: mesh.h:254
BoundingBox mesh_box_
Bounding box of whole mesh.
Definition: mesh.h:399
Definition: mesh.h:95
Input::Record in_record_
Definition: mesh.h:410
int * get_el_4_loc() const
Definition: mesh.h:175
vector< vector< vector< unsigned int > > > side_nodes
Definition: mesh.h:284
int n_tetrahedras
Definition: mesh.h:273
const RegionDB & region_db() const
Definition: mesh.h:160
vector< Boundary > boundary_
Definition: mesh.h:239
int * el_4_loc
Index set assigning to local element index its global index.
Definition: mesh.h:429
int * row_4_el
Index set assigning to global element index the local index used in parallel vectors.
Definition: mesh.h:427
int n_exsides
Definition: mesh.h:268
unsigned int n_vb_neighbours() const
Definition: mesh.h:188
unsigned int n_elements() const
Definition: mesh.h:146
MPI_Comm get_comm() const
Definition: mesh.h:181
unsigned int n_boundaries() const
Definition: mesh.h:150
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
Class for O(log N) lookup for intersections with a set of bounding boxes.
Definition: bih_tree.hh:36
ElementVector bc_elements
Definition: mesh.h:243
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:186
std::shared_ptr< BIHTree > bih_tree_
Definition: mesh.h:404
Distribution * get_el_ds() const
Definition: mesh.h:169
vector< vector< unsigned int > > master_elements
Definition: mesh.h:260
vector< Neighbour > vb_neighbours_
Definition: mesh.h:265
unsigned int n_vb_neigh
Definition: mesh.h:372
unsigned int n_all_input_elements_
Number of elements read from input.
Definition: mesh.h:380
int n_sides_
Definition: mesh.h:269
unsigned int max_edge_sides(unsigned int dim) const
Definition: mesh.h:196
int * get_row_4_el() const
Definition: mesh.h:172
RegionDB region_db_
Definition: mesh.h:389
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Definition: mesh.h:246
MPI_Comm comm_
Definition: mesh.h:415
int n_insides
Definition: mesh.h:267
#define MPI_COMM_WORLD
Definition: mpi.h:123
unsigned int n_nodes() const
Definition: mesh.h:142
Record type proxy class.
Definition: type_record.hh:177
IntersectionSearch
Types of search algorithm for finding intersection candidates.
Definition: mesh.h:110
unsigned int n_edges() const
Definition: mesh.h:154
vector< int > bulk_elements_id_
Definition: mesh.h:378
Template for classes storing finite set of named values.
std::shared_ptr< Partitioning > part_
Definition: mesh.h:393
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:233
Main class for computation of intersection of meshes of combined dimensions.
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:235
std::vector< BoundingBox > element_box_
Auxiliary vector of mesh elements bounding boxes.
Definition: mesh.h:396