PolyFEM
Loading...
Searching...
No Matches
MeshData.cpp
Go to the documentation of this file.
1#include "MeshData.hpp"
2
4
5namespace polyfem::mesh
6{
7 void MeshData::validate() const
8 {
9 if (vertices.rows() == 0 || (vertices.cols() != 2 && vertices.cols() != 3))
10 log_and_throw_error("MeshData vertices must be a nonempty n x 2 or n x 3 matrix.");
11 if (elements.rows() == 0 || elements.cols() < dimension() + 1)
12 log_and_throw_error("MeshData elements have invalid dimensions.");
13
14 for (int i = 0; i < elements.rows(); ++i)
15 {
16 int count = 0;
17 bool found_padding = false;
18 for (int j = 0; j < elements.cols(); ++j)
19 {
20 const int vertex = elements(i, j);
21 if (vertex == -1)
22 {
23 found_padding = true;
24 continue;
25 }
26 if (found_padding || vertex < 0 || vertex >= vertices.rows())
27 log_and_throw_error("MeshData element {} contains invalid connectivity.", i);
28 ++count;
29 }
30 if (count < dimension() + 1)
31 log_and_throw_error("MeshData element {} has too few vertices.", i);
32 }
33
34 const auto require_elements = [&](const size_t size, const std::string &name) {
35 if (size != 0 && size != size_t(elements.rows()))
36 log_and_throw_error("MeshData {} has {} entries; expected {}.", name, size, elements.rows());
37 };
38 require_elements(body_ids.size(), "body_ids");
39 require_elements(geometry_ids.size(), "geometry_ids");
40 require_elements(higher_order_connectivity.size(), "higher_order_connectivity");
41 require_elements(higher_order_weights.size(), "higher_order_weights");
42 if (!node_ids.empty() && node_ids.size() != size_t(vertices.rows()))
43 log_and_throw_error("MeshData node_ids has {} entries; expected {}.", node_ids.size(), vertices.rows());
44
45 if (boundary_ids.empty() != boundary_elements.empty())
46 log_and_throw_error("MeshData boundary_elements and boundary_ids must be provided together.");
47 if (!boundary_ids.empty() && boundary_ids.size() != boundary_elements.size())
48 log_and_throw_error("MeshData boundary_elements and boundary_ids have different sizes.");
49 for (const auto &element : boundary_elements)
50 {
51 if (element.size() < size_t(dimension()))
52 log_and_throw_error("MeshData contains a boundary element with too few vertices.");
53 for (const int vertex : element)
54 if (vertex < 0 || vertex >= vertices.rows())
55 log_and_throw_error("MeshData boundary connectivity references an invalid vertex.");
56 }
57
58 if (higher_order_connectivity.empty() != (higher_order_nodes.rows() == 0))
59 log_and_throw_error("MeshData higher-order nodes and connectivity must be provided together.");
60 if (!higher_order_connectivity.empty()
61 && (higher_order_nodes.cols() != dimension() || higher_order_nodes.rows() < vertices.rows()))
62 log_and_throw_error("MeshData higher-order nodes have invalid dimensions.");
63 for (const auto &connectivity : higher_order_connectivity)
64 for (const int node : connectivity)
65 if (node < 0 || node >= higher_order_nodes.rows())
66 log_and_throw_error("MeshData higher-order connectivity references an invalid node.");
67 if (!higher_order_weights.empty())
68 {
69 if (higher_order_connectivity.empty())
70 log_and_throw_error("MeshData higher-order weights require higher-order connectivity.");
71 for (int i = 0; i < higher_order_weights.size(); ++i)
72 if (!higher_order_weights[i].empty()
73 && higher_order_weights[i].size() != higher_order_connectivity[i].size())
74 log_and_throw_error("MeshData element {} has incompatible higher-order weights.", i);
75 }
76
78 {
79 if (dimension() != 3)
80 log_and_throw_error("MeshData polyhedral topology requires three-dimensional vertices.");
81 require_elements(cell_faces.size(), "cell_faces");
82 require_elements(cell_face_orientations.size(), "cell_face_orientations");
83 require_elements(cell_is_hex.size(), "cell_is_hex");
84 if (cell_kernel_points.rows() != elements.rows() || cell_kernel_points.cols() != 3)
85 log_and_throw_error("MeshData polyhedral cells require one 3D kernel point per element.");
86 for (const auto &face : faces)
87 {
88 if (face.size() < 3)
89 log_and_throw_error("MeshData contains a polyhedral face with fewer than three vertices.");
90 for (const int vertex : face)
91 if (vertex < 0 || vertex >= vertices.rows())
92 log_and_throw_error("MeshData polyhedral face references an invalid vertex.");
93 }
94 for (int i = 0; i < elements.rows(); ++i)
95 {
96 if (cell_faces[i].size() != cell_face_orientations[i].size())
97 log_and_throw_error("MeshData cell {} has inconsistent face orientations.", i);
98 for (const int orientation : cell_face_orientations[i])
99 if (orientation != 0 && orientation != 1)
100 log_and_throw_error("MeshData cell {} has an invalid face orientation.", i);
101 for (const int face : cell_faces[i])
102 if (face < 0 || face >= faces.size())
103 log_and_throw_error("MeshData cell {} references an invalid face.", i);
104 }
105 }
106 else if (!cell_faces.empty() || !cell_face_orientations.empty() || !cell_is_hex.empty() || cell_kernel_points.size())
107 log_and_throw_error("MeshData has incomplete polyhedral topology.");
108 }
109} // namespace polyfem::mesh
Eigen::MatrixXd vertices
Definition MeshData.hpp:21
bool has_polyhedral_topology() const
Definition MeshData.hpp:19
Eigen::MatrixXd higher_order_nodes
Definition MeshData.hpp:33
std::vector< std::vector< int > > higher_order_connectivity
Definition MeshData.hpp:34
std::vector< int > node_ids
Definition MeshData.hpp:29
std::vector< int > geometry_ids
Definition MeshData.hpp:28
std::vector< std::vector< int > > boundary_elements
Definition MeshData.hpp:30
std::vector< std::vector< int > > faces
Optional topology for arbitrary polyhedral cells.
Definition MeshData.hpp:38
std::vector< int > body_ids
Definition MeshData.hpp:27
std::vector< int > boundary_ids
Definition MeshData.hpp:31
Eigen::MatrixXi elements
Definition MeshData.hpp:22
void validate() const
Definition MeshData.cpp:7
Eigen::MatrixXd cell_kernel_points
Definition MeshData.hpp:42
std::vector< std::vector< int > > cell_faces
Definition MeshData.hpp:39
std::vector< std::vector< int > > cell_face_orientations
Definition MeshData.hpp:40
std::vector< std::vector< double > > higher_order_weights
Definition MeshData.hpp:35
std::vector< bool > cell_is_hex
Definition MeshData.hpp:41
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:73