Flow123d  release_2.2.0-914-gf1a3a4f
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 
84 /// Define integers that are indices into large arrays (elements, nodes, dofs etc.)
85 typedef int IdxInt;
86 
87 
89 public:
91 };
92 
93 
94 
95 //=============================================================================
96 // STRUCTURE OF THE MESH
97 //=============================================================================
98 
99 class Mesh {
100 public:
101  TYPEDEF_ERR_INFO( EI_ElemLast, int);
102  TYPEDEF_ERR_INFO( EI_ElemNew, int);
103  TYPEDEF_ERR_INFO( EI_RegLast, std::string);
104  TYPEDEF_ERR_INFO( EI_RegNew, std::string);
105  DECLARE_EXCEPTION(ExcDuplicateBoundary,
106  << "Duplicate boundary elements! \n"
107  << "Element id: " << EI_ElemLast::val << " on region name: " << EI_RegLast::val << "\n"
108  << "Element id: " << EI_ElemNew::val << " on region name: " << EI_RegNew::val << "\n");
109 
110 
111  /**
112  * \brief Types of search algorithm for finding intersection candidates.
113  */
114  typedef enum IntersectionSearch {
115  BIHsearch = 1,
116  BIHonly = 2,
117  BBsearch = 3
119 
120  /**
121  * \brief The definition of input record for selection of variant of file format
122  */
123  static const Input::Type::Selection & get_input_intersection_variant();
124 
125  static const unsigned int undef_idx=-1;
126  static const Input::Type::Record & get_input_type();
127 
128 
129 
130  /** Labels for coordinate indexes in arma::vec3 representing vectors and points.*/
131  enum {x_coord=0, y_coord=1, z_coord=2};
132 
133  /**
134  * Empty constructor.
135  *
136  * Use only for unit tests!!!
137  */
138  Mesh();
139  /**
140  * Constructor from an input record.
141  * Do not process input record. That is done in init_from_input.
142  */
143  Mesh(Input::Record in_record, MPI_Comm com = MPI_COMM_WORLD);
144  /**
145  * Common part of both previous constructors and way how to reinitialize a mesh from the given input record.
146  */
147  void reinit(Input::Record in_record);
148 
149  /// Destructor.
150  ~Mesh();
151 
152  inline unsigned int n_nodes() const {
153  return node_vector.size();
154  }
155 
156  inline unsigned int n_elements() const {
157  return element.size();
158  }
159 
160  inline unsigned int n_boundaries() const {
161  return boundary_.size();
162  }
163 
164  inline unsigned int n_edges() const {
165  return edges.size();
166  }
167 
168  unsigned int n_corners();
169 
170  inline const RegionDB &region_db() const {
171  return region_db_;
172  }
173 
174  /// Reserve size of node vector
175  inline void reserve_node_size(unsigned int n_nodes) {
176  node_vector.reserve(n_nodes);
177  }
178 
179  /// Reserve size of element vector
180  inline void reserve_element_size(unsigned int n_elements) {
181  element.reserve(n_elements);
182  }
183 
184  /**
185  * Returns pointer to partitioning object. Partitioning is created during setup_topology.
186  */
187  Partitioning *get_part();
188 
190  { return el_ds; }
191 
193  { return row_4_el; }
194 
196  { return el_4_loc; }
197 
198  /**
199  * Returns MPI communicator of the mesh.
200  */
201  inline MPI_Comm get_comm() const { return comm_; }
202 
203 
204  MixedMeshIntersections &mixed_intersections();
205 
206  unsigned int n_sides();
207 
208  inline unsigned int n_vb_neighbours() const {
209  return vb_neighbours_.size();
210  }
211 
212  /**
213  * Returns maximal number of sides of one edge, which connects elements of dimension @p dim.
214  * @param dim Dimension of elements sharing the edge.
215  */
216  unsigned int max_edge_sides(unsigned int dim) const { return max_edge_sides_[dim-1]; }
217 
218  /**
219  * Reads mesh from stream.
220  *
221  * Method is especially used in unit tests.
222  */
223  void read_gmsh_from_stream(istream &in);
224  /**
225  * Reads input record, creates regions, read the mesh, setup topology. creates region sets.
226  */
227  void init_from_input();
228 
229 
230  /**
231  * Initialize all mesh structures from raw information about nodes and elements (including boundary elements).
232  * Namely: create remaining boundary elements and Boundary objects, find edges and compatible neighborings.
233  */
234  void setup_topology();
235 
236  /**
237  * Returns vector of ID numbers of elements, either bulk or bc elemnts.
238  */
239  void elements_id_maps( vector<IdxInt> & bulk_elements_id, vector<IdxInt> & boundary_elements_id) const;
240 
241 
242  ElementAccessor<3> element_accessor(unsigned int idx, bool boundary=false);
243 
244  /**
245  * Reads elements and their affiliation to regions and region sets defined by user in input file
246  * Format of input record is defined in method RegionSetBase::get_input_type()
247  *
248  * @param region_list Array input AbstractRecords which define regions, region sets and elements
249  */
250  void read_regions_from_input(Input::Array region_list);
251 
252  /**
253  * Returns nodes_elements vector, if doesn't exist creates its.
254  */
255  vector<vector<unsigned int> > const & node_elements();
256 
257  /// Vector of nodes of the mesh.
259  /// Vector of elements of the mesh.
261 
262  /// Vector of boundary sides where is prescribed boundary condition.
263  /// TODO: apply all boundary conditions in the main assembling cycle over elements and remove this Vector.
265  /// vector of boundary elements - should replace 'boundary'
266  /// 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
267  /// the avoid usage of ElementVector etc.
269 
270  /// Vector of MH edges, this should not be part of the geometrical mesh
272 
273  //flow::VectorId<int> bcd_group_id; // gives a index of group for an id
274 
275  /**
276  * Vector of individual intersections of two elements.
277  * This is enough for local mortar.
278  */
279  std::shared_ptr<MixedMeshIntersections> intersections;
280 
281  /**
282  * For every element El we have vector of indices into @var intersections array for every intersection in which El is master element.
283  * This is necessary for true mortar.
284  */
286 
287  /**
288  * Vector of compatible neighbourings.
289  */
291 
292  int n_insides; // # of internal sides
293  int n_exsides; // # of external sides
294  int n_sides_; // total number of sides (should be easy to count when we have separated dimensions
295 
296  int n_lines; // Number of line elements
297  int n_triangles; // Number of triangle elements
298  int n_tetrahedras; // Number of tetrahedra elements
299 
300  // Temporary solution for numbering of nodes on sides.
301  // The data are defined in RefElement<dim>::side_nodes,
302  // Mesh::side_nodes can be removed as soon as Element
303  // is templated by dimension.
304  //
305  // for every side dimension D = 0 .. 2
306  // for every element side 0 .. D+1
307  // for every side node 0 .. D
308  // index into element node array
310 
311  /**
312  * Check usage of regions, set regions to elements defined by user, close RegionDB
313  */
314  void check_and_finish();
315 
316  /// Precompute element bounding boxes if it is not done yet.
317  void compute_element_boxes();
318 
319  /// Return the mesh bounding box. Is set after call compute_element_boxes().
321  return mesh_box_;
322  }
323 
324  /// Getter for BIH. Creates and compute BIH at first call.
325  const BIHTree &get_bih_tree();\
326 
327  /**
328  * Find intersection of element lists given by Mesh::node_elements_ for elements givne by @p nodes_list parameter.
329  * The result is placed into vector @p intersection_element_list. If the @p node_list is empty, and empty intersection is
330  * returned.
331  */
332  void intersect_element_lists(vector<unsigned int> const &nodes_list, vector<unsigned int> &intersection_element_list);
333 
334  /// Add new node of given id and coordinates to mesh
335  void add_node(unsigned int node_id, arma::vec3 coords);
336 
337  /// Add new element of given id to mesh
338  void add_element(unsigned int elm_id, unsigned int dim, unsigned int region_id, unsigned int partition_id,
339  std::vector<unsigned int> node_ids);
340 
341  /// Add new node of given id and coordinates to mesh
342  void add_physical_name(unsigned int dim, unsigned int id, std::string name);
343 
344  /// Return FilePath object representing "mesh_file" input key
345  inline FilePath mesh_file() {
346  return in_record_.val<FilePath>("mesh_file");
347  }
348 
349  /// Getter for input type selection for intersection search algorithm.
350  IntersectionSearch get_intersection_search();
351 
352  /// Maximal distance of observe point from Mesh relative to its size
353  double global_observe_radius() const;
354 
355  /// Number of elements read from input.
356  unsigned int n_all_input_elements_;
357 
358 
359 protected:
360 
361  /**
362  * This replaces read_neighbours() in order to avoid using NGH preprocessor.
363  *
364  * TODO:
365  * - Avoid maps:
366  *
367  * 4) replace EdgeVector by std::vector<Edge> (need not to know the size)
368  *
369  * 5) need not to have temporary array for Edges, only postpone setting pointers in elements and set them
370  * after edges are found; we can temporary save Edge index instead of pointer in Neigbours and elements
371  *
372  * 6) Try replace Edge * by indexes in Neigbours and elements (anyway we have mesh pointer in elements so it is accessible also from Neigbours)
373  *
374  */
375  void make_neighbours_and_edges();
376 
377  /**
378  * On edges sharing sides of many elements it may happen that each side has its nodes ordered in a different way.
379  * This method finds the permutation for each side so as to obtain the ordering of side 0.
380  */
381  void make_edge_permutations();
382  /**
383  * Create element lists for nodes in Mesh::nodes_elements.
384  */
385  void create_node_element_lists();
386  /**
387  * Remove elements with dimension not equal to @p dim from @p element_list. Index of the first element of dimension @p dim-1,
388  * 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,
389  * if more elements are found we report an user input error.
390  */
391  bool find_lower_dim_element(ElementVector&elements, vector<unsigned int> &element_list, unsigned int dim, unsigned int &element_idx);
392 
393  /**
394  * Returns true if side @p si has same nodes as in the list @p side_nodes.
395  */
396  bool same_sides(const SideIter &si, vector<unsigned int> &side_nodes);
397 
398 
399  void element_to_neigh_vb();
400 
401  void count_element_types();
402  void count_side_types();
403 
404  /**
405  * Possibly modify region id of elements sets by user in "regions" part of input file.
406  *
407  * TODO: This method needs check in issue 'Review mesh setting'.
408  * Changes have been done during generalized region key and may be causing problems
409  * during the further development.
410  */
411  void modify_element_ids(const RegionDB::MapElementIDToRegionID &map);
412 
413  unsigned int n_bb_neigh, n_vb_neigh;
414 
415  /// Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
416  unsigned int max_edge_sides_[3];
417 
418  /**
419  * Database of regions (both bulk and boundary) of the mesh. Regions are logical parts of the
420  * domain that allows setting of different data and boundary conditions on them.
421  */
423  /**
424  * Mesh partitioning. Created in setup_topology.
425  */
426  std::shared_ptr<Partitioning> part_;
427 
428  /// Auxiliary vector of mesh elements bounding boxes.
430 
431  /// Bounding box of whole mesh.
433 
434  /**
435  * BIH Tree for intersection and observe points lookup.
436  */
437  std::shared_ptr<BIHTree> bih_tree_;
438 
439 
440  /**
441  * Accessor to the input record for the mesh.
442  */
444 
445  /**
446  * MPI communicator used for partitioning and ...
447  */
449 
450  // For each node the vector contains a list of elements that use this node
452 
453 
454  friend class RegionSetBase;
455  friend class Element;
456  friend class BIHTree;
457 
458 
459 
460 private:
461 
462  /// Index set assigning to global element index the local index used in parallel vectors.
464  /// Index set assigning to local element index its global index.
466  /// Parallel distribution of elements.
468 };
469 
470 
471 #include "mesh/side_impl.hh"
472 #include "mesh/element_impls.hh"
473 #include "mesh/neighbours_impl.hh"
474 
475 /**
476  * Provides for statement to iterate over the Elements of the Mesh.
477  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
478  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
479  */
480 #define FOR_ELEMENTS(_mesh_,__i) \
481  for( ElementFullIter __i( (_mesh_)->element.begin() ); \
482  __i != (_mesh_)->element.end(); \
483  ++__i)
484 
485 /**
486  * Macro for conversion form Iter to FullIter for elements.
487  */
488 #define ELEMENT_FULL_ITER(_mesh_,i) \
489  (_mesh_)->element.full_iter(i)
490 
491 /**
492  * Macro to get "NULL" ElementFullIter.
493  */
494 #define ELEMENT_FULL_ITER_NULL(_mesh_) \
495  ElementFullIter((_mesh_)->element)
496 
497 
498 #define FOR_BOUNDARIES(_mesh_,i) \
499 for( std::vector<Boundary>::iterator i= (_mesh_)->boundary_.begin(); \
500  i != (_mesh_)->boundary_.end(); \
501  ++i)
502 
503 /**
504  * Macro for conversion form Iter to FullIter for boundaries.
505  */
506 #define BOUNDARY_FULL_ITER(_mesh_,i) \
507  (_mesh_)->boundary.full_iter(i)
508 
509 /**
510  * Macro to get "NULL" BoundaryFullIter.
511  */
512 #define BOUNDARY_NULL(_mesh_) \
513  BoundaryFullIter((_mesh_)->boundary)
514 
515 
516 /**
517  * Provides for statement to iterate over the Edges of the Mesh. see FOR_ELEMENTS
518  */
519 #define FOR_EDGES(_mesh_,__i) \
520  for( vector<Edge>::iterator __i = (_mesh_)->edges.begin(); \
521  __i !=(_mesh_)->edges.end(); \
522  ++__i)
523 
524 #define FOR_SIDES(_mesh_, it) \
525  FOR_ELEMENTS((_mesh_), ele) \
526  for(SideIter it = ele->side(0); it->el_idx() < ele->n_sides(); ++it)
527 
528 #define FOR_SIDE_NODES(i,j) for((j)=0;(j)<(i)->n_nodes;(j)++)
529 
530 
531 #define FOR_NEIGHBOURS(_mesh_, it) \
532  for( std::vector<Neighbour>::iterator it = (_mesh_)->vb_neighbours_.begin(); \
533  (it)!= (_mesh_)->vb_neighbours_.end(); ++it)
534 
535 #define FOR_NEIGH_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements;(j)++)
536 #define FOR_NEIGH_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
537 
538 
539 #endif
540 //-----------------------------------------------------------------------------
541 // vim: set cindent:
int n_triangles
Definition: mesh.h:297
Distribution * el_ds
Parallel distribution of elements.
Definition: mesh.h:467
Class for the mesh partitioning. This should provide:
Definition: partitioning.hh:43
const BoundingBox & get_mesh_boungin_box()
Return the mesh bounding box. Is set after call compute_element_boxes().
Definition: mesh.h:320
int IdxInt
Define integers that are indices into large arrays (elements, nodes, dofs etc.)
Definition: mesh.h:85
Bounding box in 3d ambient space.
Definition: bounding_box.hh:45
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
int MPI_Comm
Definition: mpi.h:141
Nodes of a mesh.
static Input::Type::Record input_type
Definition: mesh.h:90
IdxInt * get_el_4_loc() const
Definition: mesh.h:195
int n_lines
Definition: mesh.h:296
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:158
std::shared_ptr< MixedMeshIntersections > intersections
Definition: mesh.h:279
BoundingBox mesh_box_
Bounding box of whole mesh.
Definition: mesh.h:432
Definition: mesh.h:99
Input::Record in_record_
Definition: mesh.h:443
vector< vector< vector< unsigned int > > > side_nodes
Definition: mesh.h:309
int n_tetrahedras
Definition: mesh.h:298
const RegionDB & region_db() const
Definition: mesh.h:170
vector< Boundary > boundary_
Definition: mesh.h:264
int n_exsides
Definition: mesh.h:293
unsigned int n_vb_neighbours() const
Definition: mesh.h:208
unsigned int n_elements() const
Definition: mesh.h:156
MPI_Comm get_comm() const
Definition: mesh.h:201
unsigned int n_boundaries() const
Definition: mesh.h:160
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
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:268
void reserve_element_size(unsigned int n_elements)
Reserve size of element vector.
Definition: mesh.h:180
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:194
std::shared_ptr< BIHTree > bih_tree_
Definition: mesh.h:437
Distribution * get_el_ds() const
Definition: mesh.h:189
vector< vector< unsigned int > > node_elements_
Definition: mesh.h:451
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
vector< vector< unsigned int > > master_elements
Definition: mesh.h:285
vector< Neighbour > vb_neighbours_
Definition: mesh.h:290
unsigned int n_vb_neigh
Definition: mesh.h:413
unsigned int n_all_input_elements_
Number of elements read from input.
Definition: mesh.h:356
int n_sides_
Definition: mesh.h:294
unsigned int max_edge_sides(unsigned int dim) const
Definition: mesh.h:216
FilePath mesh_file()
Return FilePath object representing "mesh_file" input key.
Definition: mesh.h:345
IdxInt * row_4_el
Index set assigning to global element index the local index used in parallel vectors.
Definition: mesh.h:463
RegionDB region_db_
Definition: mesh.h:422
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Definition: mesh.h:271
MPI_Comm comm_
Definition: mesh.h:448
int n_insides
Definition: mesh.h:292
#define MPI_COMM_WORLD
Definition: mpi.h:123
unsigned int n_nodes() const
Definition: mesh.h:152
Record type proxy class.
Definition: type_record.hh:182
IntersectionSearch
Types of search algorithm for finding intersection candidates.
Definition: mesh.h:114
unsigned int n_edges() const
Definition: mesh.h:164
void reserve_node_size(unsigned int n_nodes)
Reserve size of node vector.
Definition: mesh.h:175
Template for classes storing finite set of named values.
IdxInt * get_row_4_el() const
Definition: mesh.h:192
std::shared_ptr< Partitioning > part_
Definition: mesh.h:426
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:258
Main class for computation of intersection of meshes of combined dimensions.
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:260
std::vector< BoundingBox > element_box_
Auxiliary vector of mesh elements bounding boxes.
Definition: mesh.h:429
IdxInt * el_4_loc
Index set assigning to local element index its global index.
Definition: mesh.h:465