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