Hermes2D  3.0
mesh_util.h
1 // This file is part of Hermes2D.
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
15 
16 #ifndef __H2D_MESH_UTIL_H
17 #define __H2D_MESH_UTIL_H
18 
19 #include "element.h"
20 #include "curved.h"
21 
22 namespace Hermes
23 {
24  namespace Hermes2D
25  {
26  class MeshHashGrid;
27  class Mesh;
28  class Nurbs;
29 
30  typedef std::tr1::shared_ptr<Hermes::Hermes2D::Mesh> MeshSharedPtr;
31 
33  {
34  public:
35  MeshHashGridElement(double lower_left_x, double lower_left_y, double upper_right_x, double upper_right_y, int depth = 0);
37 
39  Hermes::Hermes2D::Element* getElement(double x, double y);
40 
41  private:
42  inline bool belongs(double x, double y);
43  bool belongs(Hermes::Hermes2D::Element* element);
44  void insert(Hermes::Hermes2D::Element* element);
45 
46  double lower_left_x;
47  double lower_left_y;
48  double upper_right_x;
49  double upper_right_y;
50 
51  Hermes::Hermes2D::Element** elements;
52  int element_count;
53  MeshHashGridElement* m_sons[2][2];
54  int m_depth;
55 
56  static const int MAX_ELEMENTS = 50;
57  static const int MAX_DEPTH = 10;
58  bool m_active;
59  friend class MeshHashGrid;
60  };
61 
62 #define GRID_SIZE 50
63 
64  class HERMES_API MeshUtil
65  {
66  public:
68  static void assign_curve(Node* en, Curve* curve, int p1, int p2);
69 
74  static Curve* reverse_curve(Curve* curve);
75 
77  static Node* get_base_edge_node(Element* base, int edge);
78 
80  static int get_edge_sons(Element* e, int edge, int& son1, int& son2);
81 
85  static Arc* load_arc(MeshSharedPtr mesh, int id, Node** en, int p1, int p2, double angle, bool skip_check = false);
86  };
87 
89  {
90  public:
91  MeshHashGrid(Mesh* mesh);
92  ~MeshHashGrid();
93 
94  // smallest box interval_x X interval_y in which element is contained. If element is curvilinear, has to be made larger
95  // if we knew more about the shape of curvilinear element, this increase could be smaller
96  static void elementBoundingBox(Hermes::Hermes2D::Element* element, double2& p1, double2& p2);
97 
98  Hermes::Hermes2D::Element* getElement(double x, double y);
99 
100  int get_mesh_seq() const;
101 
102  private:
103  MeshHashGridElement* m_grid[GRID_SIZE][GRID_SIZE];
104 
105  double intervals_x[GRID_SIZE + 1];
106  double intervals_y[GRID_SIZE + 1];
107 
109  int mesh_seq;
110  };
111 
113  {
114  public:
115  MarkerArea(Mesh* mesh, int marker);
116  double get_area() const;
117  int get_mesh_seq() const;
118 
119  private:
120  void calculate();
121 
122  double area;
123  int mesh_seq;
124  };
125 
126  /* node and son numbering on a triangle:
127 
128  -Triangle to triangles refinement
129 
130  vn[2] vn[2]
131 
132  * *
133 
134  / \ / \
135  / \ / \
136  / \ / \
137  / \ / son[2]\
138  / \ /_________\
139  en[2] / \ en[1] vn[0] * * vn[1]
140  * * vn[1] *-----------* vn[0]
141  / \ vn[2] * \ / * vn[2]
142  / \ / \ \ son[3]/ / \
143  / \ / \ \ / / \
144  / \ / \ \ / / \
145  / \ / son[0]\ \ / /son[1] \
146  / \ / \ * / \
147  *-------------*-------------* *-----------* *-----------*
148  vn[0] vn[1] vn[2] vn[0] vn[1]
149  vn[0] en[0] vn[1]
150 
151  -Triangle to quads refinement
152 
153  vn[2] vn[2]
154 
155  * *
156  / \ / \
157  / \ / \
158  / \ / \
159  / \ vn[3] * son[2]* vn[1]
160  / \ vn[3] * \ / * vn[2]
161  en[2] * * en[1] / \ \ / / \
162  / \ / \ vn[0] / \
163  / \ / \ * / \
164  / \ / \ / \
165  / * \ / vn[2] * * vn[3] \
166  / \ / | | \
167  / \ / son[0] | | son[1] \
168  / \ / | | \
169  *-------------*-------------* *-------------* *-------------*
170  vn[0] vn[1] vn[0] vn[1]
171  vn[0] en[0] vn[1]
172 
173  node and son numbering on a quad: refinement '0':
174 
175  vn[3] en[2] vn[2] vn[3] vn[2] vn[3] vn[2]
176 
177  *-------------*-------------* *------------* *------------*
178  | | | | | |
179  | | | | | |
180  | | | son[3] | | son[2] |
181  | | | | | |
182  | | | vn[1]| |vn[0] |
183  | | vn[0] *------------* *------------* vn[1]
184  en[3] * * en[1] vn[3] *------------* *------------* vn[2]
185  | | | vn[2]| |vn[3] |
186  | | | | | |
187  | | | son[0] | | son[1] |
188  | | | | | |
189  | | | | | |
190  | | *------------* *------------*
191  *-------------*-------------*
192  vn[0] vn[1] vn[0] vn[1]
193  vn[0] en[0] vn[1]
194 
195  refinement '1': refinement '2':
196 
197  vn[3] vn[2] vn[3] vn[2] vn[3] vn[2]
198 
199  *---------------------------* *------------* *------------*
200  | | | | | |
201  | | | | | |
202  | son[1] | | | | |
203  | | | | | |
204  | | | | | |
205  vn[0] *---------------------------* vn[1] | | | |
206  vn[3] *---------------------------* vn[2] | son[2] | | son[3] |
207  | | | | | |
208  | | | | | |
209  | son[0] | | | | |
210  | | | | | |
211  | | | | | |
212  *---------------------------* *------------* *------------*
213 
214  vn[0] vn[1] vn[0] vn[1] vn[0] vn[1]
215  */
216 
218 #define for_all_elements(e, mesh) \
219  for (int _id = 0, _max = (mesh)->get_max_element_id(); _id < _max; _id++) \
220  if (((e) = (mesh)->get_element_fast(_id)) != nullptr)
221 
222 #define for_all_used_elements(e, mesh) \
223  for (int _id = 0, _max = (mesh)->get_max_element_id(); _id < _max; _id++) \
224  if (((e) = (mesh)->get_element_fast(_id))->used)
225 
226 #define for_all_base_elements(e, mesh) \
227  for (int _id = 0; _id < (mesh)->get_num_base_elements(); _id++) \
228  if (((e) = (mesh)->get_element_fast(_id))->used)
229 
230 #define for_all_base_elements_incl_inactive(e, mesh) \
231  for (int _id = 0; _id < (mesh)->get_num_base_elements(); _id++) \
232  if (((e) = (mesh)->get_element_fast(_id))->used || !((e) = (mesh)->get_element_fast(_id))->used)
233 
234 #define for_all_active_elements_fast(mesh) \
235  Element* e; \
236  for (int _id = 0, _max = (mesh)->get_max_element_id(); _id < _max; _id++) \
237  if (((e) = (mesh)->get_element_fast(_id))->used) \
238  if ((e)->active)
239 
240 #define for_all_active_elements(e, mesh) \
241  for (int _id = 0, _max = (mesh)->get_max_element_id(); _id < _max; _id++) \
242  if (((e) = (mesh)->get_element_fast(_id))->used) \
243  if ((e)->active)
244 
245 #define for_all_inactive_elements(e, mesh) \
246  for (int _id = 0, _max = (mesh)->get_max_element_id(); _id < _max; _id++) \
247  if (((e) = (mesh)->get_element_fast(_id))->used) \
248  if (!(e)->active)
249 
250 #define for_all_nodes(n, mesh) \
251  for (int _id = 0, _max = (mesh)->get_max_node_id(); _id < _max; _id++) \
252  if (((n) = (mesh)->get_node(_id))->used)
253 
254 #define for_all_vertex_nodes(n, mesh) \
255  for (int _id = 0, _max = (mesh)->get_max_node_id(); _id < _max; _id++) \
256  if (((n) = (mesh)->get_node(_id))->used) \
257  if (!(n)->type)
258 
259 #define for_all_edge_nodes(n, mesh) \
260  for (int _id = 0, _max = (mesh)->get_max_node_id(); _id < _max; _id++) \
261  if (((n) = (mesh)->get_node(_id))->used) \
262  if ((n)->type)
263  }
264 }
265 #endif
Definition: adapt.h:24
Stores one element of a mesh.
Definition: element.h:107
Represents a finite element mesh. Typical usage: MeshSharedPtr mesh; Hermes::Hermes2D::MeshReaderH2DX...
Definition: mesh.h:61
Hermes::Hermes2D::Element * getElement(double x, double y)
Return the Element.
Definition: mesh_util.cpp:322
Stores one node of a mesh.
Definition: element.h:45