Flow123d  release_1.8.2-2141-g34b6400
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/intersection.hh"
33 #include "mesh/partitioning.hh"
34 #include "mesh/region_set.hh"
35 
36 
39 #include "system/exceptions.hh"
40 
41 
42 
43 
44 #define ELM 0
45 #define BC 1
46 #define NODE 2
47 
48 /**
49  * This parameter limits volume of elements from below.
50  */
51 #define MESH_CRITICAL_VOLUME 1.0E-12
52 
53 /**
54  * Provides for statement to iterate over the Nodes of the Mesh.
55  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
56  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
57  */
58 #define FOR_NODES(_mesh_, i) \
59  for( NodeFullIter i( (_mesh_)->node_vector.begin() ); \
60  i != (_mesh_)->node_vector.end(); \
61  ++i)
62 
63 /**
64  * Macro for conversion form Iter to FullIter for nodes.
65  */
66 #define NODE_FULL_ITER(_mesh_,i) \
67  (_mesh_)->node_vector.full_iter(i)
68 
69 /**
70  * Macro to get "NULL" ElementFullIter.
71  */
72 #define NODE_FULL_ITER_NULL(_mesh_) \
73  NodeFullIter((_mesh_)->node_vector)
74 
75 /**
76  * Macro for conversion form Iter to FullIter for elements.
77  */
78 #define ELEM_FULL_ITER(_mesh_,i) \
79  (_mesh_)->element.full_iter(i)
80 
81 
82 #define FOR_NODE_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements();(j)++)
83 #define FOR_NODE_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
84 
85 
87 public:
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  static const unsigned int undef_idx=-1;
109  static const Input::Type::Record & get_input_type();
110 
111 
112 
113  /** Labels for coordinate indexes in arma::vec3 representing vectors and points.*/
114  enum {x_coord=0, y_coord=1, z_coord=2};
115 
116  /**
117  * Constructor with input record given by string. Aimed for testing purpose.
118  * Do not process input record. That is done in init_from_input.
119  */
120  Mesh(const std::string &input_str="{mesh_file=\"\"}", MPI_Comm com = MPI_COMM_WORLD);
121  /**
122  * Constructor from an input record.
123  * Do not process input record. That is done in init_from_input.
124  */
125  Mesh(Input::Record in_record, MPI_Comm com = MPI_COMM_WORLD);
126  /**
127  * Common part of both previous constructors and way how to reinitialize a mesh from the given input record.
128  */
129  void reinit(Input::Record in_record);
130 
131  /// Destructor.
132  ~Mesh();
133 
134  inline unsigned int n_nodes() const {
135  return node_vector.size();
136  }
137 
138  inline unsigned int n_elements() const {
139  return element.size();
140  }
141 
142  inline unsigned int n_boundaries() const {
143  return boundary_.size();
144  }
145 
146  inline unsigned int n_edges() const {
147  return edges.size();
148  }
149 
150  unsigned int n_corners();
151 
152  inline const RegionDB &region_db() const {
153  return region_db_;
154  }
155 
156  /**
157  * Returns pointer to partitioning object. Partitioning is created during setup_topology.
158  */
160 
162  { return el_ds; }
163 
164  int *get_row_4_el() const
165  { return row_4_el; }
166 
167  int *get_el_4_loc() const
168  { return el_4_loc; }
169 
170  /**
171  * Returns MPI communicator of the mesh.
172  */
173  inline MPI_Comm get_comm() const { return comm_; }
174 
175 
176  void make_intersec_elements();
177 
178  unsigned int n_sides();
179 
180  inline unsigned int n_vb_neighbours() const {
181  return vb_neighbours_.size();
182  }
183 
184  /**
185  * Returns maximal number of sides of one edge, which connects elements of dimension @p dim.
186  * @param dim Dimension of elements sharing the edge.
187  */
188  unsigned int max_edge_sides(unsigned int dim) const { return max_edge_sides_[dim-1]; }
189 
190  /**
191  * Reads mesh from stream.
192  *
193  * Method is especially used in unit tests.
194  */
195  void read_gmsh_from_stream(istream &in);
196  /**
197  * Reads input record, creates regions, read the mesh, setup topology. creates region sets.
198  */
199  void init_from_input();
200 
201 
202  /**
203  * Returns vector of ID numbers of elements, either bulk or bc elemnts.
204  */
205  vector<int> const & elements_id_maps( bool boundary_domain) const;
206 
207 
208  ElementAccessor<3> element_accessor(unsigned int idx, bool boundary=false);
209 
210  /**
211  * Reads elements and their affiliation to regions and region sets defined by user in input file
212  * Format of input record is defined in method RegionSetBase::get_input_type()
213  *
214  * @param region_list Array input AbstractRecords which define regions, region sets and elements
215  */
216  void read_regions_from_input(Input::Array region_list);
217 
218  /// Vector of nodes of the mesh.
220  /// Vector of elements of the mesh.
222 
223  /// Vector of boundary sides where is prescribed boundary condition.
224  /// TODO: apply all boundary conditions in the main assembling cycle over elements and remove this Vector.
226  /// vector of boundary elements - should replace 'boundary'
227  /// 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
228  /// the avoid usage of ElementVector etc.
230 
231  /// Vector of MH edges, this should not be part of the geometrical mesh
233 
234  //flow::VectorId<int> bcd_group_id; // gives a index of group for an id
235 
236  /**
237  * Vector of individual intersections of two elements.
238  * This is enough for local mortar.
239  */
241 
242  /**
243  * For every element El we have vector of indices into @var intersections array for every intersection in which El is master element.
244  * This is necessary for true mortar.
245  */
247 
248  /**
249  * Vector of compatible neighbourings.
250  */
252 
253  int n_insides; // # of internal sides
254  int n_exsides; // # of external sides
255  int n_sides_; // total number of sides (should be easy to count when we have separated dimensions
256 
257  int n_lines; // Number of line elements
258  int n_triangles; // Number of triangle elements
259  int n_tetrahedras; // Number of tetrahedra elements
260 
261  // Temporary solution for numbering of nodes on sides.
262  // The data are defined in RefElement<dim>::side_nodes,
263  // Mesh::side_nodes can be removed as soon as Element
264  // is templated by dimension.
265  //
266  // for every side dimension D = 0 .. 2
267  // for every element side 0 .. D+1
268  // for every side node 0 .. D
269  // index into element node array
271 
272  /**
273  * Check usage of regions, set regions to elements defined by user, close RegionDB
274  */
275  void check_and_finish();
276 
277  const BIHTree &get_bih_tree();
278 
279  // For each node the vector contains a list of elements that use this node
281 
282 
283 protected:
284 
285  /**
286  * This replaces read_neighbours() in order to avoid using NGH preprocessor.
287  *
288  * TODO:
289  * - Avoid maps:
290  *
291  * 4) replace EdgeVector by std::vector<Edge> (need not to know the size)
292  *
293  * 5) need not to have temporary array for Edges, only postpone setting pointers in elements and set them
294  * after edges are found; we can temporary save Edge index instead of pointer in Neigbours and elements
295  *
296  * 6) Try replace Edge * by indexes in Neigbours and elements (anyway we have mesh pointer in elements so it is accessible also from Neigbours)
297  *
298  */
300 
301  /**
302  * On edges sharing sides of many elements it may happen that each side has its nodes ordered in a different way.
303  * This method finds the permutation for each side so as to obtain the ordering of side 0.
304  */
305  void make_edge_permutations();
306  /**
307  * Create element lists for nodes in Mesh::nodes_elements.
308  */
310  /**
311  * Find intersection of element lists given by Mesh::node_elements for elements givne by @p nodes_list parameter.
312  * The result is placed into vector @p intersection_element_list. If the @p node_list is empty, and empty intersection is
313  * returned.
314  */
315  void intersect_element_lists(vector<unsigned int> const &nodes_list, vector<unsigned int> &intersection_element_list);
316  /**
317  * Remove elements with dimension not equal to @p dim from @p element_list. Index of the first element of dimension @p dim-1,
318  * 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,
319  * if more elements are found we report an user input error.
320  */
321  bool find_lower_dim_element(ElementVector&elements, vector<unsigned int> &element_list, unsigned int dim, unsigned int &element_idx);
322 
323  /**
324  * Returns true if side @p si has same nodes as in the list @p side_nodes.
325  */
327 
328  /**
329  * Initialize all mesh structures from raw information about nodes and elements (including boundary elements).
330  * Namely: create remaining boundary elements and Boundary objects, find edges and compatible neighborings.
331  */
332  void setup_topology();
333 
334 
335  void element_to_neigh_vb();
336 
337  void count_element_types();
338  void count_side_types();
339 
340  /**
341  * Possibly modify region id of elements sets by user in "regions" part of input file.
342  *
343  * TODO: This method needs check in issue 'Review mesh setting'.
344  * Changes have been done during generalized region key and may be causing problems
345  * during the further development.
346  */
348 
349  unsigned int n_bb_neigh, n_vb_neigh;
350 
351  /// Vector of both bulk and boundary IDs. Bulk elements come first, then boundary elements, but only the portion that appears
352  /// in input mesh file and has ID assigned.
353  ///
354  /// 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)
356  /// Number of elements read from input.
357  unsigned int n_all_input_elements_;
358 
359  /// Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
360  unsigned int max_edge_sides_[3];
361 
362  /**
363  * Database of regions (both bulk and boundary) of the mesh. Regions are logical parts of the
364  * domain that allows setting of different data and boundary conditions on them.
365  */
367  /**
368  * Mesh partitioning. Created in setup_topology.
369  */
370  std::shared_ptr<Partitioning> part_;
371 
372  /**
373  * BIH Tree for intersection and observe points lookup.
374  */
375  std::shared_ptr<BIHTree> bih_tree_;
376  /**
377  * Accessor to the input record for the mesh.
378  */
380 
381  /**
382  * MPI communicator used for partitioning and ...
383  */
385 
386  friend class GmshMeshReader;
387  friend class RegionSetBase;
388 
389 
390 private:
391 
392  /// Index set assigning to global element index the local index used in parallel vectors.
393  int *row_4_el;
394  /// Index set assigning to local element index its global index.
395  int *el_4_loc;
396  /// Parallel distribution of elements.
398 };
399 
400 
401 #include "mesh/side_impl.hh"
402 #include "mesh/element_impls.hh"
403 #include "mesh/neighbours_impl.hh"
404 
405 /**
406  * Provides for statement to iterate over the Elements of the Mesh.
407  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
408  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
409  */
410 #define FOR_ELEMENTS(_mesh_,__i) \
411  for( ElementFullIter __i( (_mesh_)->element.begin() ); \
412  __i != (_mesh_)->element.end(); \
413  ++__i)
414 
415 /**
416  * Macro for conversion form Iter to FullIter for elements.
417  */
418 #define ELEMENT_FULL_ITER(_mesh_,i) \
419  (_mesh_)->element.full_iter(i)
420 
421 /**
422  * Macro to get "NULL" ElementFullIter.
423  */
424 #define ELEMENT_FULL_ITER_NULL(_mesh_) \
425  ElementFullIter((_mesh_)->element)
426 
427 
428 #define FOR_BOUNDARIES(_mesh_,i) \
429 for( std::vector<Boundary>::iterator i= (_mesh_)->boundary_.begin(); \
430  i != (_mesh_)->boundary_.end(); \
431  ++i)
432 
433 /**
434  * Macro for conversion form Iter to FullIter for boundaries.
435  */
436 #define BOUNDARY_FULL_ITER(_mesh_,i) \
437  (_mesh_)->boundary.full_iter(i)
438 
439 /**
440  * Macro to get "NULL" BoundaryFullIter.
441  */
442 #define BOUNDARY_NULL(_mesh_) \
443  BoundaryFullIter((_mesh_)->boundary)
444 
445 
446 /**
447  * Provides for statement to iterate over the Edges of the Mesh. see FOR_ELEMENTS
448  */
449 #define FOR_EDGES(_mesh_,__i) \
450  for( vector<Edge>::iterator __i = (_mesh_)->edges.begin(); \
451  __i !=(_mesh_)->edges.end(); \
452  ++__i)
453 
454 #define FOR_SIDES(_mesh_, it) \
455  FOR_ELEMENTS((_mesh_), ele) \
456  for(SideIter it = ele->side(0); it->el_idx() < ele->n_sides(); ++it)
457 
458 #define FOR_SIDE_NODES(i,j) for((j)=0;(j)<(i)->n_nodes;(j)++)
459 
460 
461 #define FOR_NEIGHBOURS(_mesh_, it) \
462  for( std::vector<Neighbour>::iterator it = (_mesh_)->vb_neighbours_.begin(); \
463  (it)!= (_mesh_)->vb_neighbours_.end(); ++it)
464 
465 #define FOR_NEIGH_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements;(j)++)
466 #define FOR_NEIGH_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
467 
468 
469 #endif
470 //-----------------------------------------------------------------------------
471 // vim: set cindent:
int n_triangles
Definition: mesh.h:258
Distribution * el_ds
Parallel distribution of elements.
Definition: mesh.h:397
Class for the mesh partitioning. This should provide:
Definition: partitioning.hh:39
Mesh(const std::string &input_str="{mesh_file=\"\"}", MPI_Comm com=MPI_COMM_WORLD)
Definition: mesh.cc:75
vector< vector< unsigned int > > node_elements
Definition: mesh.h:280
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
unsigned int n_bb_neigh
Definition: mesh.h:349
void count_side_types()
Definition: mesh.cc:289
int MPI_Comm
Definition: mpi.h:141
void make_intersec_elements()
Definition: mesh.cc:661
Nodes of a mesh.
void check_and_finish()
Definition: mesh.cc:751
static Input::Type::Record input_type
Definition: mesh.h:88
int n_lines
Definition: mesh.h:257
static const unsigned int undef_idx
Definition: mesh.h:108
void create_node_element_lists()
Definition: mesh.cc:302
static const Input::Type::Record & get_input_type()
Definition: mesh.cc:57
unsigned int max_edge_sides_[3]
Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
Definition: mesh.h:360
Definition: mesh.h:95
Input::Record in_record_
Definition: mesh.h:379
int * get_el_4_loc() const
Definition: mesh.h:167
vector< vector< vector< unsigned int > > > side_nodes
Definition: mesh.h:270
int n_tetrahedras
Definition: mesh.h:259
const RegionDB & region_db() const
Definition: mesh.h:152
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:700
vector< Boundary > boundary_
Definition: mesh.h:225
Partitioning * get_part()
Definition: mesh.cc:191
unsigned int n_sides()
Definition: mesh.cc:172
int * el_4_loc
Index set assigning to local element index its global index.
Definition: mesh.h:395
int * row_4_el
Index set assigning to global element index the local index used in parallel vectors.
Definition: mesh.h:393
int n_exsides
Definition: mesh.h:254
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:391
unsigned int n_vb_neighbours() const
Definition: mesh.h:180
void read_regions_from_input(Input::Array region_list)
Definition: mesh.cc:741
unsigned int n_elements() const
Definition: mesh.h:138
bool same_sides(const SideIter &si, vector< unsigned int > &side_nodes)
Definition: mesh.cc:363
MPI_Comm get_comm() const
Definition: mesh.h:173
vector< int > const & elements_id_maps(bool boundary_domain) const
Definition: mesh.cc:706
void setup_topology()
Definition: mesh.cc:261
unsigned int n_boundaries() const
Definition: mesh.h:142
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
Class for O(log N) lookup for intersections with a set of bounding boxes.
Definition: bih_tree.hh:36
unsigned int n_corners()
Definition: mesh.cc:181
ElementVector bc_elements
Definition: mesh.h:229
std::shared_ptr< BIHTree > bih_tree_
Definition: mesh.h:375
Distribution * get_el_ds() const
Definition: mesh.h:161
vector< int > boundary_elements_id_
Definition: mesh.h:355
void count_element_types()
Definition: mesh.cc:200
const BIHTree & get_bih_tree()
Definition: mesh.cc:764
void read_gmsh_from_stream(istream &in)
Definition: mesh.cc:216
vector< vector< unsigned int > > master_elements
Definition: mesh.h:246
vector< Neighbour > vb_neighbours_
Definition: mesh.h:251
unsigned int n_vb_neigh
Definition: mesh.h:349
unsigned int n_all_input_elements_
Number of elements read from input.
Definition: mesh.h:357
int n_sides_
Definition: mesh.h:255
unsigned int max_edge_sides(unsigned int dim) const
Definition: mesh.h:188
int * get_row_4_el() const
Definition: mesh.h:164
RegionDB region_db_
Definition: mesh.h:366
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Definition: mesh.h:232
vector< Intersection > intersections
Definition: mesh.h:240
MPI_Comm comm_
Definition: mesh.h:384
int n_insides
Definition: mesh.h:253
void intersect_element_lists(vector< unsigned int > const &nodes_list, vector< unsigned int > &intersection_element_list)
Definition: mesh.cc:315
void modify_element_ids(const RegionDB::MapElementIDToRegionID &map)
Definition: mesh.cc:251
#define MPI_COMM_WORLD
Definition: mpi.h:123
void make_edge_permutations()
Definition: mesh.cc:555
unsigned int n_nodes() const
Definition: mesh.h:134
Record type proxy class.
Definition: type_record.hh:171
unsigned int n_edges() const
Definition: mesh.h:146
void element_to_neigh_vb()
Definition: mesh.cc:626
TYPEDEF_ERR_INFO(EI_ElemLast, int)
void reinit(Input::Record in_record)
Definition: mesh.cc:102
void init_from_input()
Definition: mesh.cc:230
bool find_lower_dim_element(ElementVector &elements, vector< unsigned int > &element_list, unsigned int dim, unsigned int &element_idx)
Definition: mesh.cc:343
DECLARE_EXCEPTION(ExcDuplicateBoundary,<< "Duplicate boundary elements! \n"<< "Element id: "<< EI_ElemLast::val<< " on region name: "<< EI_RegLast::val<< "\n"<< "Element id: "<< EI_ElemNew::val<< " on region name: "<< EI_RegNew::val<< "\n")
vector< int > bulk_elements_id_
Definition: mesh.h:355
std::shared_ptr< Partitioning > part_
Definition: mesh.h:370
void make_neighbours_and_edges()
Definition: mesh.cc:380
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:219
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:221
~Mesh()
Destructor.
Definition: mesh.cc:147