Flow123d  jenkins-Flow123d-windows-release-multijob-285
mesh.h
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief ???
27  *
28  */
29 
30 #ifndef MAKE_MESH_H
31 #define MAKE_MESH_H
32 
33 #include <vector>
34 #include <mpi.h>
35 
36 #include "mesh/mesh_types.hh"
37 
38 #include "mesh/nodes.hh"
39 #include "mesh/elements.h"
40 #include "mesh/sides.h"
41 #include "mesh/edges.h"
42 #include "mesh/neighbours.h"
43 #include "mesh/boundaries.h"
44 #include "mesh/intersection.hh"
45 #include "mesh/partitioning.hh"
46 
47 #include "input/input_type.hh"
48 #include "input/accessors.hh"
49 #include "boost/shared_ptr.hpp"
50 
51 // Forward declarations
52 template <int spacedim>
53 class ElementAccessor;
54 class GmshMeshReader;
55 
56 
57 
58 #define ELM 0
59 #define BC 1
60 #define NODE 2
61 
62 /**
63  * This parameter limits volume of elements from below.
64  */
65 #define MESH_CRITICAL_VOLUME 1.0E-12
66 
67 /**
68  * Provides for statement to iterate over the Nodes of the Mesh.
69  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
70  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
71  */
72 #define FOR_NODES(_mesh_, i) \
73  for( NodeFullIter i( (_mesh_)->node_vector.begin() ); \
74  i != (_mesh_)->node_vector.end(); \
75  ++i)
76 
77 /**
78  * Macro for conversion form Iter to FullIter for nodes.
79  */
80 #define NODE_FULL_ITER(_mesh_,i) \
81  (_mesh_)->node_vector.full_iter(i)
82 
83 /**
84  * Macro to get "NULL" ElementFullIter.
85  */
86 #define NODE_FULL_ITER_NULL(_mesh_) \
87  NodeFullIter((_mesh_)->node_vector)
88 
89 /**
90  * Macro for conversion form Iter to FullIter for elements.
91  */
92 #define ELEM_FULL_ITER(_mesh_,i) \
93  (_mesh_)->element.full_iter(i)
94 
95 
96 #define FOR_NODE_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements();(j)++)
97 #define FOR_NODE_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
98 
99 
101 public:
103 };
104 
105 //=============================================================================
106 // STRUCTURE OF THE MESH
107 //=============================================================================
108 
109 class Mesh {
110 public:
111  static const unsigned int undef_idx=-1;
113 
114 
115 
116  /** Labels for coordinate indexes in arma::vec3 representing vectors and points.*/
117  enum {x_coord=0, y_coord=1, z_coord=2};
118 
119  /**
120  * Constructor with input record given by string. Aimed for testing purpose.
121  * Do not process input record. That is done in init_from_input.
122  */
123  Mesh(const std::string &input_str="{mesh_file=\"\"}", MPI_Comm com = MPI_COMM_WORLD);
124  /**
125  * Constructor from an input record.
126  * Do not process input record. That is done in init_from_input.
127  */
128  Mesh(Input::Record in_record, MPI_Comm com = MPI_COMM_WORLD);
129  /**
130  * Common part of both previous constructors and way how to reinitialize a mesh from the given input record.
131  */
132  void reinit(Input::Record in_record);
133 
134  /// Destructor.
135  ~Mesh();
136 
137  inline unsigned int n_nodes() const {
138  return node_vector.size();
139  }
140 
141  inline unsigned int n_elements() const {
142  return element.size();
143  }
144 
145  inline unsigned int n_boundaries() const {
146  return boundary_.size();
147  }
148 
149  inline unsigned int n_edges() const {
150  return edges.size();
151  }
152 
153  unsigned int n_corners();
154 
155  inline const RegionDB &region_db() const {
156  return region_db_;
157  }
158 
159  /**
160  * Returns pointer to partitioning object. Partitioning is created during setup_topology.
161  */
163 
164  /**
165  * Returns MPI communicator of the mesh.
166  */
167  inline MPI_Comm get_comm() const { return comm_; }
168 
169 
170  void make_intersec_elements();
171 
172  unsigned int n_sides();
173 
174  inline unsigned int n_vb_neighbours() const {
175  return vb_neighbours_.size();
176  }
177 
178  /**
179  * Returns maximal number of sides of one edge, which connects elements of dimension @p dim.
180  * @param dim Dimension of elements sharing the edge.
181  */
182  unsigned int max_edge_sides(unsigned int dim) const { return max_edge_sides_[dim-1]; }
183 
184  /**
185  *
186  */
187  void read_gmsh_from_stream(istream &in);
188  /**
189  * Reads input record, creates regions, read the mesh, setup topology. creates region sets.
190  */
191  void init_from_input();
192 
193 
194  /**
195  * Returns vector of ID numbers of elements, either bulk or bc elemnts.
196  */
197  vector<int> const & elements_id_maps( bool boundary_domain) const;
198 
199 
200  ElementAccessor<3> element_accessor(unsigned int idx, bool boundary=false);
201 
202  /// Vector of nodes of the mesh.
204  /// Vector of elements of the mesh.
206 
207  /// Vector of boundary sides where is prescribed boundary condition.
208  /// TODO: apply all boundary conditions in the main assembling cycle over elements and remove this Vector.
210  /// vector of boundary elements - should replace 'boundary'
211  /// 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
212  /// the avoid usage of ElementVector etc.
214 
215  /// Vector of MH edges, this should not be part of the geometrical mesh
217 
218  //flow::VectorId<int> bcd_group_id; // gives a index of group for an id
219 
220  /**
221  * Vector of individual intersections of two elements.
222  * This is enough for local mortar.
223  */
225 
226  /**
227  * For every element El we have vector of indices into @var intersections array for every intersection in which El is master element.
228  * This is necessary for true mortar.
229  */
231 
232  /**
233  * Vector of compatible neighbourings.
234  */
236 
237  int n_insides; // # of internal sides
238  int n_exsides; // # of external sides
239  int n_sides_; // total number of sides (should be easy to count when we have separated dimensions
240 
241  int n_lines; // Number of line elements
242  int n_triangles; // Number of triangle elements
243  int n_tetrahedras; // Number of tetrahedra elements
244 
245  // Temporary solution for numbering of nodes on sides.
246  // The data are defined in RefElement<dim>::side_nodes,
247  // Mesh::side_nodes can be removed as soon as Element
248  // is templated by dimension.
249  //
250  // for every side dimension D = 0 .. 2
251  // for every element side 0 .. D+1
252  // for every side node 0 .. D
253  // index into element node array
255 
256 
257 
258 
259 protected:
260 
261  /**
262  * This replaces read_neighbours() in order to avoid using NGH preprocessor.
263  *
264  * TODO:
265  * - Avoid maps:
266  *
267  * 4) replace EdgeVector by std::vector<Edge> (need not to know the size)
268  *
269  * 5) need not to have temporary array for Edges, only postpone setting pointers in elements and set them
270  * after edges are found; we can temporary save Edge index instead of pointer in Neigbours and elements
271  *
272  * 6) Try replace Edge * by indexes in Neigbours and elements (anyway we have mesh pointer in elements so it is accessible also from Neigbours)
273  *
274  */
276 
277  /**
278  * On edges sharing sides of many elements it may happen that each side has its nodes ordered in a different way.
279  * This method finds the permutation for each side so as to obtain the ordering of side 0.
280  */
281  void make_edge_permutations();
282  /**
283  * Create element lists for nodes in Mesh::nodes_elements.
284  */
286  /**
287  * Find intersection of element lists given by Mesh::node_elements for elements givne by @p nodes_list parameter.
288  * The result is placed into vector @p intersection_element_list. If the @p node_list is empty, and empty intersection is
289  * returned.
290  */
291  void intersect_element_lists(vector<unsigned int> const &nodes_list, vector<unsigned int> &intersection_element_list);
292  /**
293  * Remove elements with dimension not equal to @p dim from @p element_list. Index of the first element of dimension @p dim-1,
294  * 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,
295  * if more elements are found we report an user input error.
296  */
297  bool find_lower_dim_element(ElementVector&elements, vector<unsigned int> &element_list, unsigned int dim, unsigned int &element_idx);
298 
299  /**
300  * Returns true if side @p si has same nodes as in the list @p side_nodes.
301  */
302  bool same_sides(const SideIter &si, vector<unsigned int> &side_nodes);
303 
304  /**
305  * Initialize all mesh structures from raw information about nodes and elements (including boundary elements).
306  * Namely: create remaining boundary elements and Boundary objects, find edges and compatible neighborings.
307  */
308  void setup_topology();
309 
310 
311  void element_to_neigh_vb();
312 
313  void count_element_types();
314  void count_side_types();
315 
316  unsigned int n_bb_neigh, n_vb_neigh;
317 
318  /// Vector of both bulk and boundary IDs. Bulk elements come first, then boundary elements, but only the portion that appears
319  /// in input mesh file and has ID assigned.
320  ///
321  /// 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)
323  /// Number of elements read from input.
324  unsigned int n_all_input_elements_;
325 
326  // For each node the vector contains a list of elements that use this node
328 
329  /// Maximal number of sides per one edge in the actual mesh (set in make_neighbours_and_edges()).
330  unsigned int max_edge_sides_[3];
331 
332  /**
333  * Database of regions (both bulk and boundary) of the mesh. Regions are logical parts of the
334  * domain that allows setting of different data and boundary conditions on them.
335  */
337  /**
338  * Mesh partitioning. Created in setup_topology.
339  */
340  boost::shared_ptr<Partitioning> part_;
341  /**
342  * Accessor to the input record for the mesh.
343  */
345 
346  /**
347  * MPI communicator used for partitioning and ...
348  */
350 
351  friend class GmshMeshReader;
352 };
353 
354 
355 #include "mesh/side_impl.hh"
356 #include "mesh/element_impls.hh"
357 #include "mesh/neighbours_impl.hh"
358 
359 /**
360  * Provides for statement to iterate over the Elements of the Mesh.
361  * The parameter is FullIter local variable of the cycle, so it need not be declared before.
362  * Macro assume that variable Mesh *mesh; is declared and points to a valid Mesh structure.
363  */
364 #define FOR_ELEMENTS(_mesh_,__i) \
365  for( ElementFullIter __i( (_mesh_)->element.begin() ); \
366  __i != (_mesh_)->element.end(); \
367  ++__i)
368 
369 /**
370  * Macro for conversion form Iter to FullIter for elements.
371  */
372 #define ELEMENT_FULL_ITER(_mesh_,i) \
373  (_mesh_)->element.full_iter(i)
374 
375 /**
376  * Macro to get "NULL" ElementFullIter.
377  */
378 #define ELEMENT_FULL_ITER_NULL(_mesh_) \
379  ElementFullIter((_mesh_)->element)
380 
381 
382 #define FOR_BOUNDARIES(_mesh_,i) \
383 for( std::vector<Boundary>::iterator i= (_mesh_)->boundary_.begin(); \
384  i != (_mesh_)->boundary_.end(); \
385  ++i)
386 
387 /**
388  * Macro for conversion form Iter to FullIter for boundaries.
389  */
390 #define BOUNDARY_FULL_ITER(_mesh_,i) \
391  (_mesh_)->boundary.full_iter(i)
392 
393 /**
394  * Macro to get "NULL" BoundaryFullIter.
395  */
396 #define BOUNDARY_NULL(_mesh_) \
397  BoundaryFullIter((_mesh_)->boundary)
398 
399 
400 /**
401  * Provides for statement to iterate over the Edges of the Mesh. see FOR_ELEMENTS
402  */
403 #define FOR_EDGES(_mesh_,__i) \
404  for( vector<Edge>::iterator __i = (_mesh_)->edges.begin(); \
405  __i !=(_mesh_)->edges.end(); \
406  ++__i)
407 
408 #define FOR_SIDES(_mesh_, it) \
409  FOR_ELEMENTS((_mesh_), ele) \
410  for(SideIter it = ele->side(0); it->el_idx() < ele->n_sides(); ++it)
411 
412 #define FOR_SIDE_NODES(i,j) for((j)=0;(j)<(i)->n_nodes;(j)++)
413 
414 
415 #define FOR_NEIGHBOURS(_mesh_, it) \
416  for( std::vector<Neighbour>::iterator it = (_mesh_)->vb_neighbours_.begin(); \
417  (it)!= (_mesh_)->vb_neighbours_.end(); ++it)
418 
419 #define FOR_NEIGH_ELEMENTS(i,j) for((j)=0;(j)<(i)->n_elements;(j)++)
420 #define FOR_NEIGH_SIDES(i,j) for((j)=0;(j)<(i)->n_sides;(j)++)
421 
422 
423 #endif
424 //-----------------------------------------------------------------------------
425 // vim: set cindent:
int n_triangles
Definition: mesh.h:242
Class for the mesh partitioning. This should provide:
Definition: partitioning.hh:29
Mesh(const std::string &input_str="{mesh_file=\"\"}", MPI_Comm com=MPI_COMM_WORLD)
Definition: mesh.cc:85
vector< vector< unsigned int > > node_elements
Definition: mesh.h:327
unsigned int n_bb_neigh
Definition: mesh.h:316
void count_side_types()
Definition: mesh.cc:272
int MPI_Comm
Definition: mpi.h:141
void make_intersec_elements()
Definition: mesh.cc:631
Nodes of a mesh.
static Input::Type::Record input_type
Definition: mesh.h:102
int n_lines
Definition: mesh.h:241
static const unsigned int undef_idx
Definition: mesh.h:111
void create_node_element_lists()
Definition: mesh.cc:285
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:330
boost::shared_ptr< Partitioning > part_
Definition: mesh.h:340
Definition: mesh.h:109
Input::Record in_record_
Definition: mesh.h:344
vector< vector< vector< unsigned int > > > side_nodes
Definition: mesh.h:254
int n_tetrahedras
Definition: mesh.h:243
const RegionDB & region_db() const
Definition: mesh.h:155
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:670
vector< Boundary > boundary_
Definition: mesh.h:209
Partitioning * get_part()
Definition: mesh.cc:191
unsigned int n_sides()
Definition: mesh.cc:172
int n_exsides
Definition: mesh.h:238
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:401
unsigned int n_vb_neighbours() const
Definition: mesh.h:174
unsigned int n_elements() const
Definition: mesh.h:141
bool same_sides(const SideIter &si, vector< unsigned int > &side_nodes)
Definition: mesh.cc:346
MPI_Comm get_comm() const
Definition: mesh.h:167
vector< int > const & elements_id_maps(bool boundary_domain) const
Definition: mesh.cc:676
void setup_topology()
Definition: mesh.cc:252
unsigned int n_boundaries() const
Definition: mesh.h:145
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
unsigned int n_corners()
Definition: mesh.cc:181
ElementVector bc_elements
Definition: mesh.h:213
vector< int > boundary_elements_id_
Definition: mesh.h:322
void count_element_types()
Definition: mesh.cc:200
void read_gmsh_from_stream(istream &in)
Definition: mesh.cc:216
vector< vector< unsigned int > > master_elements
Definition: mesh.h:230
vector< Neighbour > vb_neighbours_
Definition: mesh.h:235
unsigned int n_vb_neigh
Definition: mesh.h:316
unsigned int n_all_input_elements_
Number of elements read from input.
Definition: mesh.h:324
int n_sides_
Definition: mesh.h:239
unsigned int max_edge_sides(unsigned int dim) const
Definition: mesh.h:182
static Input::Type::Record input_type
Definition: mesh.h:112
RegionDB region_db_
Definition: mesh.h:336
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Definition: mesh.h:216
vector< Intersection > intersections
Definition: mesh.h:224
MPI_Comm comm_
Definition: mesh.h:349
int n_insides
Definition: mesh.h:237
void intersect_element_lists(vector< unsigned int > const &nodes_list, vector< unsigned int > &intersection_element_list)
Definition: mesh.cc:298
#define MPI_COMM_WORLD
Definition: mpi.h:123
void make_edge_permutations()
Definition: mesh.cc:525
unsigned int n_nodes() const
Definition: mesh.h:137
Record type proxy class.
Definition: type_record.hh:169
unsigned int n_edges() const
Definition: mesh.h:149
void element_to_neigh_vb()
Definition: mesh.cc:596
void reinit(Input::Record in_record)
Definition: mesh.cc:106
void init_from_input()
Definition: mesh.cc:227
bool find_lower_dim_element(ElementVector &elements, vector< unsigned int > &element_list, unsigned int dim, unsigned int &element_idx)
Definition: mesh.cc:326
vector< int > bulk_elements_id_
Definition: mesh.h:322
void make_neighbours_and_edges()
Definition: mesh.cc:363
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:203
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:205
~Mesh()
Destructor.
Definition: mesh.cc:151