11#ifndef _MESHOBJECT_HPP
12#define _MESHOBJECT_HPP
16 template <
size_t space_dim>
17 using VectorRd = Eigen::Matrix<double, space_dim, 1>;
19 template <
size_t space_dim>
20 using VectorZd = Eigen::Matrix<int, space_dim, 1>;
22 template <
size_t space_dim,
size_t object_dim>
23 using Simplex = std::array<VectorRd<space_dim>, object_dim + 1>;
25 template <
size_t space_dim,
size_t object_dim>
26 using Simplices = std::vector<Simplex<space_dim, object_dim>>;
29 template <
size_t space_dim,
size_t object_dim>
33 template <
size_t space_dim,
size_t object_dim>
55 template <
size_t space_dim,
size_t object_dim>
79 inline double diam()
const {
return _diameter; }
83 inline double measure()
const {
return _measure; }
95 inline bool is_flat()
const {
return _is_flat; }
98 inline std::vector<MeshObject<space_dim, 0>*>
get_vertices()
const {
return _vertices; }
100 inline std::vector<MeshObject<space_dim, 1>*>
get_edges()
const {
return _edges; }
104 inline std::vector<MeshObject<space_dim, space_dim>*>
get_cells()
const {
return _cells; }
107 inline size_t n_vertices()
const {
return _vertices.size(); }
109 inline size_t n_edges()
const {
return _edges.size(); }
111 inline size_t n_faces()
const {
return _faces.size(); }
113 inline size_t n_cells()
const {
return _cells.size(); }
156 std::vector<int> _face_directions;
158 std::vector<MeshObject<space_dim, 0>*> _vertices;
159 std::vector<MeshObject<space_dim, 1>*> _edges;
160 std::vector<
MeshObject<space_dim, space_dim - 1>*> _faces;
161 std::vector<MeshObject<space_dim, space_dim>*> _cells;
165 template <
size_t space_dim>
169 template <
size_t space_dim>
173 template <
size_t space_dim>
177 template <
size_t space_dim>
186 template <
size_t space_dim,
size_t object_dim>
191 for (
auto& coord : simplex)
193 for (
size_t i = 0; i < space_dim; ++i)
195 center_mass(i) += coord(i);
198 return center_mass / (object_dim + 1);
201 template <
size_t space_dim,
size_t object_dim>
204 Eigen::MatrixXd CM_mat = Eigen::MatrixXd::Zero(object_dim + 2, object_dim + 2);
205 for (
size_t i = 0; i < object_dim + 1; ++i)
208 for (
size_t j = i + 1; j < object_dim + 1; ++j)
211 double norm = (j_coords - i_coords).norm();
212 CM_mat(i, j) = norm * norm;
213 CM_mat(j, i) = CM_mat(i, j);
215 CM_mat(i, object_dim + 1) = 1;
216 CM_mat(object_dim + 1, i) = 1;
220 double det = CM_mat.determinant();
221 double scaling = std::pow(
Math::factorial(object_dim), 2) * std::pow(2, object_dim);
223 return std::sqrt(std::abs(det / scaling));
226 template <
size_t space_dim,
size_t object_dim>
228 : _index(index), _simplices(simplices)
230 assert(space_dim >= object_dim);
231 assert(space_dim >= 2);
233 if (object_dim == 0 || object_dim == 1)
235 assert(simplices.size() == 1);
238 _is_boundary =
false;
241 _center_mass = Eigen::VectorXd::Zero(space_dim);
242 std::vector<VectorRd<space_dim>> vertex_coords;
243 for (
auto& simplex : simplices)
246 double tmp = simplex_measure<space_dim, object_dim>(simplex);
248 _center_mass += tmp * simplex_center_mass<space_dim, object_dim>(simplex);
249 for (
auto& coord : simplex)
251 if (std::find(vertex_coords.begin(), vertex_coords.end(), coord) == vertex_coords.end())
253 vertex_coords.push_back(coord);
257 _center_mass /= _measure;
260 for (
auto it = vertex_coords.begin(); it != vertex_coords.end(); ++it)
262 for (
auto jt = it; jt != vertex_coords.end(); ++jt)
264 _diameter = std::max(_diameter, (*it - *jt).norm());
270 if (object_dim == space_dim - 1)
274 std::vector<VectorRd<space_dim>> points_in_face;
275 for (
size_t i = 0; i < _simplices.size(); ++i)
277 for (
size_t j = 0; j < space_dim; ++j)
279 if( (std::find(points_in_face.begin(), points_in_face.end(), _simplices[i][j]) == points_in_face.end()) && ( (_simplices[i][j]-_center_mass).norm()>1e-8 * _diameter) )
281 points_in_face.push_back(_simplices[i][j]);
287 double norm_perp_vec = 0.;
288 for (
size_t iV = 0 ; iV < points_in_face.size(); iV++){
290 for (
size_t iVp = iV+1; iVp < points_in_face.size(); iVp++){
293 double norm_tmp = tmp.norm();
294 if (norm_tmp > norm_perp_vec){
296 norm_perp_vec = norm_tmp;
300 _normal = perp_vec / norm_perp_vec;
303 for (
size_t iV = 0; iV < points_in_face.size(); iV++){
305 if (std::abs( v_xF.dot(_normal) ) > 1e-8 * v_xF.norm()){
313 template <
size_t space_dim,
size_t object_dim>
319 template <
size_t space_dim,
size_t object_dim>
323 assert(object_dim == 0);
326 template <
size_t space_dim,
size_t object_dim>
329 template <
size_t space_dim,
size_t object_dim>
332 template <
size_t space_dim,
size_t object_dim>
335 assert(std::find(_vertices.begin(), _vertices.end(), vertex) == _vertices.end());
336 _vertices.push_back(vertex);
339 template <
size_t space_dim,
size_t object_dim>
342 assert(std::find(_edges.begin(), _edges.end(), edge) == _edges.end());
343 _edges.push_back(edge);
346 assert(std::find(_faces.begin(), _faces.end(),
reinterpret_cast<MeshObject<space_dim, space_dim - 1
> *>(edge)) == _faces.end());
347 _faces.push_back(
reinterpret_cast<MeshObject<space_dim, space_dim - 1
> *>(edge));
351 template <
size_t space_dim,
size_t object_dim>
354 assert(std::find(_faces.begin(), _faces.end(), face) == _faces.end());
355 _faces.push_back(face);
358 assert(std::find(_edges.begin(), _edges.end(),
reinterpret_cast<MeshObject<space_dim, 1> *
>(face)) == _edges.end());
363 template <
size_t space_dim,
size_t object_dim>
366 assert(std::find(_cells.begin(), _cells.end(), cell) == _cells.end());
367 _cells.push_back(cell);
370 template <
size_t space_dim,
size_t object_dim>
373 assert(i < _vertices.size());
377 template <
size_t space_dim,
size_t object_dim>
380 assert(i < _edges.size());
384 template <
size_t space_dim,
size_t object_dim>
387 assert(i < _faces.size());
391 template <
size_t space_dim,
size_t object_dim>
394 assert(i < _cells.size());
398 template <
size_t space_dim,
size_t object_dim>
401 assert(object_dim == space_dim);
402 for (
size_t iF = 0; iF < _faces.size(); ++iF)
408 for (
auto& cell_simplex : this->get_simplices())
411 for (
size_t i = 0; (i < cell_simplex.size()) && count < 2; ++i)
413 if (std::find(face_simplex.begin(), face_simplex.end(), cell_simplex[i]) == face_simplex.end())
420 center = simplex_center_mass<space_dim, object_dim>(cell_simplex);
426 _face_directions.push_back(
Math::sgn((_faces[iF]->center_mass() - center).dot(normal)));
427 assert(_face_directions[iF] != 0);
431 template <
size_t space_dim,
size_t object_dim>
434 assert(object_dim == space_dim);
435 assert(face_index < _faces.size());
436 return _face_directions[face_index] * _faces[face_index]->normal();
439 template <
size_t space_dim,
size_t object_dim>
442 assert(object_dim == 2);
445 return this->face_normal(edge_index);
454 template <
size_t space_dim,
size_t object_dim>
457 assert(object_dim == 0);
458 return this->get_simplices()[0][0];
461 template <
size_t space_dim,
size_t object_dim>
464 assert(object_dim == 0);
465 this->set_simplices()[0][0] = x;
468 template <
size_t space_dim,
size_t object_dim>
471 assert(object_dim == space_dim - 1);
475 template <
size_t space_dim,
size_t object_dim>
478 assert(object_dim == 1);
479 return (this->get_vertices()[1]->coords() - this->get_vertices()[0]->coords()).normalized();
482 template <
size_t space_dim,
size_t object_dim>
485 assert(object_dim == 2);
486 Eigen::Matrix<double,space_dim,2> rv;
487 rv.col(0) = edge(0)->tangent();
488 rv.col(1) = edge_normal(0);
492 template <
size_t space_dim,
size_t object_dim>
495 auto itr = std::find(_vertices.begin(), _vertices.end(), vertex);
496 if (itr != _vertices.end())
498 return itr - _vertices.begin();
502 throw "Vertex not found";
506 template <
size_t space_dim,
size_t object_dim>
509 auto itr = std::find(_edges.begin(), _edges.end(), edge);
510 if (itr != _edges.end())
512 return itr - _edges.begin();
516 throw "Edge not found";
520 template <
size_t space_dim,
size_t object_dim>
523 auto itr = std::find(_faces.begin(), _faces.end(), face);
524 if (itr != _faces.end())
526 return itr - _faces.begin();
530 throw "Face not found";
534 template <
size_t space_dim,
size_t object_dim>
537 auto itr = std::find(_cells.begin(), _cells.end(), cell);
538 if (itr != _cells.end())
540 return itr - _cells.begin();
544 throw "Cell not found";
547 template <
size_t space_dim,
size_t object_dim>
550 assert(object_dim == space_dim);
551 assert(face_index < _faces.size());
552 return _face_directions[face_index];
554 template <
size_t space_dim,
size_t object_dim>
557 assert(object_dim == 2);
558 assert(edge_index < _edges.size());
559 return Math::sgn((_edges[edge_index]->center_mass() - this->center_mass()).dot(this->edge_normal(edge_index)));
561 template <
size_t space_dim,
size_t object_dim>
564 assert((object_dim == 2 && index < _edges.size())||(object_dim == 3 && index < _faces.size()));
565 if constexpr(object_dim == 2) {
567 t = edge(index)->tangent();
568 Eigen::Matrix<double,space_dim,2>
const ab = face_tangent();
569 return Math::sgn(ab.col(0).dot(n)*ab.col(1).dot(t) - ab.col(0).dot(t)*ab.col(1).dot(n));
575 Eigen::Matrix<double,space_dim,object_dim> nab;
576 nab.rightCols(2) = face(index)->face_tangent();
577 nab.leftCols(1) = face_normal(index);
Generic class to describe a cell, face, edge or vertex.
Definition MeshObject.hpp:57
std::vector< MeshObject< space_dim, 0 > * > get_vertices() const
Returns the vertices of the MeshObject.
Definition MeshObject.hpp:98
int index_edge(const MeshObject< space_dim, 1 > *edge) const
Returns the local index of an edge.
Definition MeshObject.hpp:507
~MeshObject()
Destructor.
Definition MeshObject.hpp:330
double simplex_measure(Simplex< space_dim, object_dim > simplex)
Method to find the Lebesgue measure of an arbitrary simplex in arbitrary space.
Definition MeshObject.hpp:202
int face_orientation(const size_t face_index) const
Return the orientation of a Face.
Definition MeshObject.hpp:548
void add_face(MeshObject< space_dim, space_dim - 1 > *face)
Add a face to the MeshObject.
Definition MeshObject.hpp:352
int edge_orientation(const size_t edge_index) const
Return the orientation of a Edge (multiplied by edge_normal, gives the outer normal to the face)
Definition MeshObject.hpp:555
size_t n_vertices() const
Returns the number of vertices of the MeshObject.
Definition MeshObject.hpp:107
Simplices< space_dim, object_dim > & set_simplices()
Definition MeshObject.hpp:87
VectorRd< space_dim > simplex_center_mass(Simplex< space_dim, object_dim > simplex)
Method to find the center mass of an arbitrary simplex in arbitrary space.
Definition MeshObject.hpp:187
MeshObject< space_dim, space_dim - 1 > * face(const size_t i) const
Returns the i-th face of the MeshObject.
Definition MeshObject.hpp:385
size_t n_cells() const
Returns the number of cells of the MeshObject.
Definition MeshObject.hpp:113
MeshObject< space_dim, space_dim > * cell(const size_t i) const
Returns the i-th cell of the MeshObject.
Definition MeshObject.hpp:392
VectorRd< space_dim > face_normal(const size_t face_index) const
Return the outer normal of a Cell towards the Face located at face_index.
Definition MeshObject.hpp:432
double diam() const
Returns the diameter of the MeshObject.
Definition MeshObject.hpp:79
VectorRd< space_dim > center_mass() const
Returns the center mass of the MeshObject.
Definition MeshObject.hpp:81
VectorRd< space_dim > coords() const
Return the coordinates of a Vertex.
Definition MeshObject.hpp:455
int induced_orientation(const size_t index) const
Return 1 if the volume form on the boundary is positively oriented, -1 else.
Definition MeshObject.hpp:562
void add_edge(MeshObject< space_dim, 1 > *edge)
Add an edge to the MeshObject.
Definition MeshObject.hpp:340
Eigen::Matrix< double, space_dim, 2 > face_tangent() const
Return the tangent space of a Face.
Definition MeshObject.hpp:483
double measure() const
Definition MeshObject.hpp:83
size_t global_index() const
Returns the global index of the MeshObject.
Definition MeshObject.hpp:77
void set_boundary(bool val)
Set the boundary value of the MeshObject.
Definition MeshObject.hpp:93
void set_coords(const VectorRd< space_dim > &x)
Set the coordinates of a Vertex.
Definition MeshObject.hpp:462
MeshObject< space_dim, 1 > * edge(const size_t i) const
Returns the i-th edge of the MeshObject.
Definition MeshObject.hpp:378
size_t n_faces() const
Returns the number of faces of the MeshObject.
Definition MeshObject.hpp:111
int index_face(const MeshObject< space_dim, space_dim - 1 > *face) const
Returns the local index of a face.
Definition MeshObject.hpp:521
void add_vertex(MeshObject< space_dim, 0 > *vertex)
Add a vertex to the MeshObject.
Definition MeshObject.hpp:333
bool is_boundary() const
Returns true if MeshObject is a boundary object, false otherwise.
Definition MeshObject.hpp:91
size_t n_edges() const
Returns the number of edges of the MeshObject.
Definition MeshObject.hpp:109
std::vector< MeshObject< space_dim, 1 > * > get_edges() const
Returns the edges of the MeshObject.
Definition MeshObject.hpp:100
MeshObject()
Null constructor.
Definition MeshObject.hpp:327
MeshObject< space_dim, 0 > * vertex(const size_t i) const
Returns the i-th vertex of the MeshObject.
Definition MeshObject.hpp:371
int index_cell(const MeshObject< space_dim, space_dim > *cell) const
Returns the local index of a cell.
Definition MeshObject.hpp:535
void set_global_index(const size_t idx)
Set the global index.
Definition MeshObject.hpp:89
Simplices< space_dim, object_dim > get_simplices() const
Returns the simplices making up the MeshObject.
Definition MeshObject.hpp:86
VectorRd< space_dim > normal() const
Return the normal of a Face.
Definition MeshObject.hpp:469
bool is_flat() const
Returns true if MeshObject is flat (only relevant for faces), false otherwise.
Definition MeshObject.hpp:95
VectorRd< space_dim > edge_normal(const size_t edge_index) const
Return the edge normal of a 2D object.
Definition MeshObject.hpp:440
VectorRd< space_dim > tangent() const
Return the tangent of a Edge.
Definition MeshObject.hpp:476
std::vector< MeshObject< space_dim, space_dim - 1 > * > get_faces() const
Returns the faces of the MeshObject.
Definition MeshObject.hpp:102
std::vector< MeshObject< space_dim, space_dim > * > get_cells() const
Return the cells of the MeshObject.
Definition MeshObject.hpp:104
void add_cell(MeshObject< space_dim, space_dim > *cell)
Add a cell to the MeshObject.
Definition MeshObject.hpp:364
void construct_face_orientations()
Set the directions of the face normals of a cell.
Definition MeshObject.hpp:399
int index_vertex(const MeshObject< space_dim, 0 > *vertex) const
Returns the local index of a vertex.
Definition MeshObject.hpp:493
const int sgn(T val)
Definition math.hpp:41
const size_t factorial(size_t n)
Definition math.hpp:11
Eigen::Matrix< double, space_dim, 1 > VectorRd
Definition MeshObject.hpp:17
Eigen::Matrix< int, space_dim, 1 > VectorZd
Definition MeshObject.hpp:20
std::vector< Simplex< space_dim, object_dim > > Simplices
Definition MeshObject.hpp:26
std::array< VectorRd< space_dim >, object_dim+1 > Simplex
Definition MeshObject.hpp:23