HArD::Core3D
Hybrid Arbitrary Degree::Core 3D - Library to implement 3D schemes with vertex, edge, face and cell polynomials as unknowns
MeshND.hpp
Go to the documentation of this file.
1 #include "MeshObject.hpp"
2 
3 #ifndef _MESHND_HPP
4 #define _MESHND_HPP
5 
6 
12 namespace MeshND
13 {
15  template <std::size_t dimension>
16  class Mesh
17  {
18  public:
19  Mesh() {}
21  {
22  for (auto &vertex : _vertices)
23  {
24  delete vertex;
25  }
26  for (auto &edge : _edges)
27  {
28  delete edge;
29  }
30  if (dimension != 2) // if dimension == 2, faces are edges (which are already deleted)
31  {
32  for (auto &face : _faces)
33  {
34  delete face;
35  }
36  }
37  for (auto &cell : _cells)
38  {
39  delete cell;
40  }
41  }
42 
43  void set_name(std::string name) { _mesh_name = name; }
44  inline std::string get_name() { return _mesh_name; }
45 
46  double h_max() const
47  {
48  double val = 0.0;
49  for (auto &cell : _cells)
50  {
51  val = std::max(val, cell->diam());
52  }
53  return val;
54  }
55  inline std::size_t dim() const { return dimension; }
56 
57  inline std::size_t n_vertices() const { return _vertices.size(); }
58  inline std::size_t n_edges() const { return _edges.size(); }
59  inline std::size_t n_faces() const { return _faces.size(); }
60  inline std::size_t n_cells() const { return _cells.size(); }
61  inline std::size_t n_elems(size_t d) const
62  {
63  assert(d <= dimension && dimension < 4);
64  if (d == dimension) {
65  return n_cells();
66  } else if (d == 2) {
67  return n_faces();
68  } else if (d == 1) {
69  return n_edges();
70  } else {
71  return n_vertices();
72  }
73  }
74 
75  inline std::size_t n_b_vertices() const { return _b_vertices.size(); }
76  inline std::size_t n_b_edges() const { return _b_edges.size(); }
77  inline std::size_t n_b_faces() const { return _b_faces.size(); }
78  inline std::size_t n_b_cells() const { return _b_cells.size(); }
79 
80  inline std::size_t n_i_vertices() const { return _i_vertices.size(); }
81  inline std::size_t n_i_edges() const { return _i_edges.size(); }
82  inline std::size_t n_i_faces() const { return _i_faces.size(); }
83  inline std::size_t n_i_cells() const { return _i_cells.size(); }
84 
85  inline std::vector<Vertex<dimension> *> get_vertices() const { return _vertices; }
86  inline std::vector<Edge<dimension> *> get_edges() const { return _edges; }
87  inline std::vector<Face<dimension> *> get_faces() const { return _faces; }
88  inline std::vector<Cell<dimension> *> get_cells() const { return _cells; }
89 
90  inline std::vector<Vertex<dimension> *> get_b_vertices() const { return _b_vertices; }
91  inline std::vector<Edge<dimension> *> get_b_edges() const { return _b_edges; }
92  inline std::vector<Face<dimension> *> get_b_faces() const { return _b_faces; }
93  inline std::vector<Cell<dimension> *> get_b_cells() const { return _b_cells; }
94 
95  inline std::vector<Vertex<dimension> *> get_i_vertices() const { return _i_vertices; }
96  inline std::vector<Edge<dimension> *> get_i_edges() const { return _i_edges; }
97  inline std::vector<Face<dimension> *> get_i_faces() const { return _i_faces; }
98  inline std::vector<Cell<dimension> *> get_i_cells() const { return _i_cells; }
99 
101  {
102  assert(std::find(_vertices.begin(), _vertices.end(), vertex) == _vertices.end());
103  _vertices.push_back(vertex);
104  }
106  {
107  assert(std::find(_edges.begin(), _edges.end(), edge) == _edges.end());
108  _edges.push_back(edge);
109  if (dimension == 2)
110  {
111  assert(std::find(_faces.begin(), _faces.end(), reinterpret_cast<Face<dimension> *>(edge)) == _faces.end());
112  _faces.push_back(reinterpret_cast<Face<dimension> *>(edge));
113  }
114  }
116  {
117  assert(std::find(_faces.begin(), _faces.end(), face) == _faces.end());
118  _faces.push_back(face);
119  if (dimension == 2)
120  {
121  assert(std::find(_edges.begin(), _edges.end(), reinterpret_cast<Edge<dimension> *>(face)) == _edges.end());
122  _edges.push_back(reinterpret_cast<Edge<dimension> *>(face));
123  }
124  }
126  {
127  assert(std::find(_cells.begin(), _cells.end(), cell) == _cells.end());
128  _cells.push_back(cell);
129  }
130 
132  {
133  assert(std::find(_b_vertices.begin(), _b_vertices.end(), vertex) == _b_vertices.end());
134  _b_vertices.push_back(vertex);
135  }
137  {
138  assert(std::find(_b_edges.begin(), _b_edges.end(), edge) == _b_edges.end());
139  _b_edges.push_back(edge);
140  if (dimension == 2)
141  {
142  assert(std::find(_b_faces.begin(), _b_faces.end(), reinterpret_cast<Face<dimension> *>(edge)) == _b_faces.end());
143  _b_faces.push_back(reinterpret_cast<Face<dimension> *>(edge));
144  }
145  }
147  {
148  assert(std::find(_b_faces.begin(), _b_faces.end(), face) == _b_faces.end());
149  _b_faces.push_back(face);
150  if (dimension == 2)
151  {
152  assert(std::find(_b_edges.begin(), _b_edges.end(), reinterpret_cast<Edge<dimension> *>(face)) == _b_edges.end());
153  _b_edges.push_back(reinterpret_cast<Edge<dimension> *>(face));
154  }
155  }
157  {
158  assert(std::find(_b_cells.begin(), _b_cells.end(), cell) == _b_cells.end());
159  _b_cells.push_back(cell);
160  }
161 
163  {
164  assert(std::find(_i_vertices.begin(), _i_vertices.end(), vertex) == _i_vertices.end());
165  _i_vertices.push_back(vertex);
166  }
168  {
169  assert(std::find(_i_edges.begin(), _i_edges.end(), edge) == _i_edges.end());
170  _b_edges.push_back(edge);
171  if (dimension == 2)
172  {
173  assert(std::find(_i_faces.begin(), _i_faces.end(), reinterpret_cast<Face<dimension> *>(edge)) == _i_faces.end());
174  _i_faces.push_back(reinterpret_cast<Face<dimension> *>(edge));
175  }
176  }
178  {
179  assert(std::find(_i_faces.begin(), _i_faces.end(), face) == _i_faces.end());
180  _i_faces.push_back(face);
181  if (dimension == 2)
182  {
183  assert(std::find(_i_edges.begin(), _i_edges.end(), reinterpret_cast<Edge<dimension> *>(face)) == _i_edges.end());
184  _i_edges.push_back(reinterpret_cast<Edge<dimension> *>(face));
185  }
186  }
188  {
189  assert(std::find(_i_cells.begin(), _i_cells.end(), cell) == _i_cells.end());
190  _i_cells.push_back(cell);
191  }
192 
193  // Note that all these assume that a MeshObject's index is equal to its position in the mesh!!
194  inline Vertex<dimension> *vertex(std::size_t index) const { assert(index < _vertices.size()); return _vertices[index]; }
195  inline Edge<dimension> *edge(std::size_t index) const { assert(index < _edges.size()); return _edges[index]; }
196  inline Face<dimension> *face(std::size_t index) const { assert(index < _faces.size()); return _faces[index]; }
197  inline Cell<dimension> *cell(std::size_t index) const { assert(index < _cells.size()); return _cells[index]; }
198 
199  inline Vertex<dimension> *b_vertex(std::size_t index) const { assert(index < _b_vertices.size()); return _b_vertices[index]; }
200  inline Edge<dimension> *b_edge(std::size_t index) const { assert(index < _b_edges.size()); return _b_edges[index]; }
201  inline Face<dimension> *b_face(std::size_t index) const { assert(index < _b_faces.size()); return _b_faces[index]; }
202  inline Cell<dimension> *b_cell(std::size_t index) const { assert(index < _b_cells.size()); return _b_cells[index]; }
203 
204  inline Vertex<dimension> *i_vertex(std::size_t index) const { assert(index < _i_vertices.size()); return _i_vertices[index]; }
205  inline Edge<dimension> *i_edge(std::size_t index) const { assert(index < _i_edges.size()); return _i_edges[index]; }
206  inline Face<dimension> *i_face(std::size_t index) const { assert(index < _i_faces.size()); return _i_faces[index]; }
207  inline Cell<dimension> *i_cell(std::size_t index) const { assert(index < _i_cells.size()); return _i_cells[index]; }
208 
209  // Return the indices of the boundary of the i-th top dimensionnal cell of the MeshObject
210  std::vector<size_t> get_boundary(size_t d,size_t index) const
211  {
212  std::vector<size_t> rv;
213  static_assert(dimension < 4);
214  assert(d <= dimension);
215  if (d == dimension) {
216  assert(index < _cells.size());
217  const Cell<dimension> & T = *_cells[index];
218  rv.reserve(T.n_faces());
219  for (size_t j = 0; j < T.n_faces(); ++j) {
220  rv.push_back(T.face(j)->global_index());
221  }
222  } else if (d == 2) { // Only reached for dimension = 3
223  assert(index < _faces.size());
224  const Face<dimension> & F = *_faces[index];
225  rv.reserve(F.n_edges());
226  for (size_t j = 0; j < F.n_edges(); ++j) {
227  rv.push_back(F.edge(j)->global_index());
228  }
229  } else if (d == 1) {
230  assert(index < _edges.size());
231  const Edge<dimension> & E = *_edges[index];
232  rv.reserve(2);
233  rv.push_back(E.vertex(0)->global_index());
234  rv.push_back(E.vertex(1)->global_index());
235  }
236  return rv;
237  }
238  // Return the orientation of the j-th boundary element of the i-th d-cell
239  int boundary_orientation(size_t d,size_t i, size_t j) const
240  {
241  static_assert(dimension < 4);
242  assert(d <= dimension);
243  if (d == dimension) {
244  assert(i < _cells.size());
245  return _cells[i]->induced_orientation(j);
246  } else if (d == 2) { // Only reached for dimension = 3
247  assert(i < _faces.size());
248  return _faces[i]->induced_orientation(j);
249  } else { // Special case for degenerate boundary
250  assert(d == 1);
251  return (j%2==0?-1:1);
252  }
253  }
254 
255  std::vector<double> regularity()
256  {
263 
264  std::vector<std::vector<double>> reg_cell(n_cells(), {0.0, 0.0});
265  std::size_t count = 0;
266  for (auto &T : _cells)
267  {
268  double hT = T->diam();
269  VectorRd<dimension> xT = T->center_mass();
270 
271  reg_cell[count][0] = hT / pow(T->measure(), 1.0 / dimension);
272 
273  double rhoT = hT;
274  std::vector<Face<dimension> *> faces = T->get_faces();
275  for (auto &F : faces)
276  {
277  double hF = F->diam();
278  VectorRd<dimension> xF = F->center_mass();
279  VectorRd<dimension> nTF = F->normal(); // sign does not matter
280 
281  reg_cell[count][0] = std::max(reg_cell[count][0], hT / hF);
282 
283  rhoT = std::min(rhoT, std::abs((xT - xF).dot(nTF))); // If xT is not in T, is this really a good measure?
284  }
285  reg_cell[count][1] = hT / rhoT;
286  ++count; //could just use iterators
287  }
288 
289  std::vector<double> value(2, 0.0);
290  for (size_t iT = 0; iT < n_cells(); iT++)
291  {
292  value[0] = std::max(value[0], reg_cell[iT][0]);
293  value[1] = std::max(value[1], reg_cell[iT][1]);
294  }
295 
296  return value;
297  }
298 
299  void renum(const char B, const std::vector<size_t> new_to_old)
300  {
301 
302  switch (B)
303  {
304  case 'C':
305  {
306  std::vector<Cell<dimension> *> old_index = _cells;
307  for (size_t i = 0; i < _cells.size(); i++)
308  {
309  old_index[new_to_old[i]]->set_global_index(i);
310  _cells[i] = old_index[new_to_old[i]];
311  }
312  break;
313  }
314  case 'F':
315  {
316  std::vector<Face<dimension> *> old_index = _faces;
317  for (size_t i = 0; i < _faces.size(); i++)
318  {
319  old_index[new_to_old[i]]->set_global_index(i);
320  _faces[i] = old_index[new_to_old[i]];
321  }
322  break;
323  }
324 
325  case 'E':
326  {
327  std::vector<Edge<dimension> *> old_index = _edges;
328  for (size_t i = 0; i < _edges.size(); i++)
329  {
330  old_index[new_to_old[i]]->set_global_index(i);
331  _edges[i] = old_index[new_to_old[i]];
332  }
333  break;
334  }
335 
336  case 'V':
337  {
338  std::vector<Vertex<dimension> *> old_index = _vertices;
339  for (size_t i = 0; i < _vertices.size(); i++)
340  {
341  old_index[new_to_old[i]]->set_global_index(i);
342  _vertices[i] = old_index[new_to_old[i]];
343  }
344  break;
345  }
346  }
347  }
348 
349  private:
350  std::string _mesh_name;
351 
352  std::vector<Vertex<dimension> *> _vertices;
353  std::vector<Edge<dimension> *> _edges;
354  std::vector<Face<dimension> *> _faces;
355  std::vector<Cell<dimension> *> _cells;
356 
357  // std::vector<MeshObject<dimension, 0> *> _vertices;
358  // std::vector<MeshObject<dimension, 1> *> _edges;
359  // std::vector<MeshObject<dimension, dimension - 1> *> _faces;
360  // std::vector<MeshObject<dimension, dimension> *> _cells;
361 
362  std::vector<Vertex<dimension> *> _b_vertices;
363  std::vector<Edge<dimension> *> _b_edges;
364  std::vector<Face<dimension> *> _b_faces;
365  std::vector<Cell<dimension> *> _b_cells;
366 
367  std::vector<Vertex<dimension> *> _i_vertices;
368  std::vector<Edge<dimension> *> _i_edges;
369  std::vector<Face<dimension> *> _i_faces;
370  std::vector<Cell<dimension> *> _i_cells;
371  };
372 } // namespace MeshND
373 
374 #endif
Generic class to describe a cell, face, edge or vertex.
Definition: MeshObject.hpp:57
Class to describe a mesh.
Definition: MeshND.hpp:17
Vertex< dimension > * vertex(std::size_t index) const
get a constant pointer to a vertex using its global index
Definition: MeshND.hpp:194
std::vector< Edge< dimension > * > get_i_edges() const
lists the internal edges in the mesh.
Definition: MeshND.hpp:96
void add_i_cell(Cell< dimension > *cell)
Definition: MeshND.hpp:187
void renum(const char B, const std::vector< size_t > new_to_old)
Definition: MeshND.hpp:299
std::vector< Face< dimension > * > get_faces() const
lists the faces in the mesh.
Definition: MeshND.hpp:87
std::vector< Face< dimension > * > get_b_faces() const
lists the boundary faces in the mesh.
Definition: MeshND.hpp:92
void set_name(std::string name)
set the name of the mesh
Definition: MeshND.hpp:43
Edge< dimension > * b_edge(std::size_t index) const
get a constant pointer to boundary a edge using an index
Definition: MeshND.hpp:200
std::size_t n_vertices() const
number of vertices in the mesh.
Definition: MeshND.hpp:57
std::size_t n_edges() const
number of edges in the mesh.
Definition: MeshND.hpp:58
double h_max() const
< max diameter of cells
Definition: MeshND.hpp:46
std::size_t dim() const
dimension of the mesh
Definition: MeshND.hpp:55
std::size_t n_i_edges() const
number of internal edges in the mesh.
Definition: MeshND.hpp:81
std::vector< Edge< dimension > * > get_edges() const
lists the edges in the mesh.
Definition: MeshND.hpp:86
std::size_t n_i_vertices() const
number of internal vertices in the mesh.
Definition: MeshND.hpp:80
Vertex< dimension > * i_vertex(std::size_t index) const
get a constant pointer to an internal vertex using an index
Definition: MeshND.hpp:204
int boundary_orientation(size_t d, size_t i, size_t j) const
Definition: MeshND.hpp:239
std::vector< Cell< dimension > * > get_cells() const
lists the cells in the mesh.
Definition: MeshND.hpp:88
std::size_t n_b_vertices() const
number of boundary vertices in the mesh.
Definition: MeshND.hpp:75
std::vector< Vertex< dimension > * > get_vertices() const
lists the vertices in the mesh.
Definition: MeshND.hpp:85
Face< dimension > * i_face(std::size_t index) const
get a constant pointer to an internal face using an index
Definition: MeshND.hpp:206
void add_face(Face< dimension > *face)
Definition: MeshND.hpp:115
std::size_t n_faces() const
number of faces in the mesh.
Definition: MeshND.hpp:59
std::vector< Edge< dimension > * > get_b_edges() const
lists the boundary edges in the mesh.
Definition: MeshND.hpp:91
Face< dimension > * face(std::size_t index) const
get a constant pointer to a face using its global index
Definition: MeshND.hpp:196
MeshObject< space_dim, space_dim - 1 > * face(const size_t i) const
Returns the i-th face of the MeshObject.
Definition: MeshObject.hpp:385
Cell< dimension > * b_cell(std::size_t index) const
get a constant pointer to boundary a cell using an index
Definition: MeshND.hpp:202
std::size_t n_cells() const
number of cells in the mesh.
Definition: MeshND.hpp:60
Edge< dimension > * i_edge(std::size_t index) const
get a constant pointer to an internal edge using an index
Definition: MeshND.hpp:205
Edge< dimension > * edge(std::size_t index) const
get a constant pointer to a edge using its global index
Definition: MeshND.hpp:195
std::vector< Face< dimension > * > get_i_faces() const
lists the internal faces in the mesh.
Definition: MeshND.hpp:97
std::size_t n_i_cells() const
number of internal cells in the mesh.
Definition: MeshND.hpp:83
std::string get_name()
getter for the mesh name
Definition: MeshND.hpp:44
void add_b_vertex(Vertex< dimension > *vertex)
Definition: MeshND.hpp:131
void add_edge(Edge< dimension > *edge)
Definition: MeshND.hpp:105
void add_i_face(Face< dimension > *face)
Definition: MeshND.hpp:177
void add_vertex(Vertex< dimension > *vertex)
Definition: MeshND.hpp:100
std::size_t n_b_edges() const
number of boundary edges in the mesh.
Definition: MeshND.hpp:76
void add_b_cell(Cell< dimension > *cell)
Definition: MeshND.hpp:156
std::size_t n_b_cells() const
number of boundary cells in the mesh.
Definition: MeshND.hpp:78
void add_i_vertex(Vertex< dimension > *vertex)
Definition: MeshND.hpp:162
std::size_t n_b_faces() const
number of boundary faces in the mesh.
Definition: MeshND.hpp:77
MeshObject< space_dim, 1 > * edge(const size_t i) const
Returns the i-th edge of the MeshObject.
Definition: MeshObject.hpp:378
void add_cell(Cell< dimension > *cell)
Definition: MeshND.hpp:125
size_t n_faces() const
Returns the number of faces of the MeshObject.
Definition: MeshObject.hpp:111
Cell< dimension > * i_cell(std::size_t index) const
get a constant pointer to an internal cell using an index
Definition: MeshND.hpp:207
std::vector< Cell< dimension > * > get_i_cells() const
lists the internal cells in the mesh.
Definition: MeshND.hpp:98
Mesh()
Definition: MeshND.hpp:19
std::size_t n_elems(size_t d) const
< number of d-cells in the mesh
Definition: MeshND.hpp:61
size_t n_edges() const
Returns the number of edges of the MeshObject.
Definition: MeshObject.hpp:109
std::vector< Vertex< dimension > * > get_b_vertices() const
lists the boundary vertices in the mesh.
Definition: MeshND.hpp:90
MeshObject< space_dim, 0 > * vertex(const size_t i) const
Returns the i-th vertex of the MeshObject.
Definition: MeshObject.hpp:371
void add_b_edge(Edge< dimension > *edge)
Definition: MeshND.hpp:136
std::vector< Vertex< dimension > * > get_i_vertices() const
lists the internal vertices in the mesh.
Definition: MeshND.hpp:95
Cell< dimension > * cell(std::size_t index) const
get a constant pointer to a cell using its global index
Definition: MeshND.hpp:197
std::size_t n_i_faces() const
number of internal faces in the mesh.
Definition: MeshND.hpp:82
~Mesh()
Definition: MeshND.hpp:20
std::vector< size_t > get_boundary(size_t d, size_t index) const
Definition: MeshND.hpp:210
void add_b_face(Face< dimension > *face)
Definition: MeshND.hpp:146
std::vector< double > regularity()
Definition: MeshND.hpp:255
void add_i_edge(Edge< dimension > *edge)
Definition: MeshND.hpp:167
Vertex< dimension > * b_vertex(std::size_t index) const
get a constant pointer to a boundary vertex using an index
Definition: MeshND.hpp:199
Face< dimension > * b_face(std::size_t index) const
get a constant pointer to boundary a face using an index
Definition: MeshND.hpp:201
std::vector< Cell< dimension > * > get_b_cells() const
lists the boundary cells in the mesh.
Definition: MeshND.hpp:93
Definition: MeshND.hpp:13
Eigen::Matrix< double, space_dim, 1 > VectorRd
Definition: MeshObject.hpp:17