PolyFEM
Loading...
Searching...
No Matches
WildRemesher.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <wmtk/TriMesh.h>
7#include <wmtk/TetMesh.h>
8#include <wmtk/ExecutionScheduler.hpp>
9
10#include <type_traits>
11
12namespace polyfem::mesh
13{
14 enum class CollapseEdgeTo
15 {
16 V0,
17 V1,
20 };
21
24
25 template <class WMTKMesh>
26 class WildRemesher : public Remesher, public WMTKMesh
27 {
29
30 // --------------------------------------------------------------------
31 // typedefs
32 public:
33 // NOTE: This assumes triangle meshes are only used in 2D.
34 static constexpr int DIM = [] {
35 if constexpr (std::is_same_v<wmtk::TriMesh, WMTKMesh>)
36 return 2;
37 else
38 return 3;
39 }();
40
41 static constexpr int VERTICES_PER_ELEMENT = [] {
42 if constexpr (std::is_same_v<wmtk::TriMesh, WMTKMesh>)
43 return 3;
44 else
45 return 4;
46 }();
47
48 static constexpr int EDGES_PER_ELEMENT = [] {
49 if constexpr (std::is_same_v<wmtk::TriMesh, WMTKMesh>)
50 return 3;
51 else
52 return 6;
53 }();
54
55 static constexpr int FACETS_PER_ELEMENT = [] {
56 if constexpr (std::is_same_v<wmtk::TriMesh, WMTKMesh>)
57 return 3;
58 else
59 return 4;
60 }();
61
62 using VectorNd = Eigen::Matrix<double, DIM, 1>;
63
64 using Tuple = typename WMTKMesh::Tuple;
65
67 static constexpr wmtk::ExecutionPolicy EXECUTION_POLICY = wmtk::ExecutionPolicy::kSeq;
68
69 // --------------------------------------------------------------------
70 // constructors
71 public:
75 const State &state,
76 const Eigen::MatrixXd &obstacle_displacements,
77 const Eigen::MatrixXd &obstacle_vals,
78 const double current_time,
79 const double starting_energy);
80
81 virtual ~WildRemesher() = default;
82
90 virtual void init(
91 const Eigen::MatrixXd &rest_positions,
92 const Eigen::MatrixXd &positions,
93 const Eigen::MatrixXi &elements,
94 const Eigen::MatrixXd &projection_quantities,
95 const BoundaryMap<int> &boundary_to_id,
96 const std::vector<int> &body_ids,
97 const EdgeMap<double> &elastic_energy,
98 const EdgeMap<double> &contact_energy) override;
99
100 protected:
103 const size_t num_vertices,
104 const Eigen::MatrixXi &elements) override;
105
106 // --------------------------------------------------------------------
107 // main functions
108 public:
116 bool execute() override;
117
118 virtual void split_edges() = 0;
119 virtual void collapse_edges() = 0;
120 virtual void smooth_vertices();
121 virtual void swap_edges() { log_and_throw_error("WildRemesher::swap_edges not implemented!"); }
122
123 protected:
124 // Edge splitting
125 virtual bool split_edge_before(const Tuple &t) override;
126 virtual bool split_edge_after(const Tuple &t) override;
127
128 // Edge collapse
129 virtual bool collapse_edge_before(const Tuple &t) override;
130 virtual bool collapse_edge_after(const Tuple &t) override;
131
132 // Swap edge
133 virtual bool swap_edge_before(const Tuple &t) override;
134 virtual bool swap_edge_after(const Tuple &t) override;
135
136 // Smooth_vertex
137 virtual bool smooth_before(const Tuple &t) override;
138 virtual bool smooth_after(const Tuple &t) override;
139
141 bool invariants(const std::vector<Tuple> &new_tris) override;
142
144 bool is_rest_inverted(const Tuple &loc) const;
146 bool is_inverted(const Tuple &loc) const;
147
148 // --------------------------------------------------------------------
149 // getters
150 public:
152 int dim() const override { return DIM; }
153
155 Eigen::MatrixXd rest_positions() const override;
157 Eigen::MatrixXd displacements() const override;
159 Eigen::MatrixXd positions() const override;
161 Eigen::MatrixXi edges() const override;
163 Eigen::MatrixXi elements() const override;
165 Eigen::MatrixXi boundary_edges() const override;
167 Eigen::MatrixXi boundary_faces() const override;
169 Eigen::MatrixXd projection_quantities() const override;
173 std::vector<int> body_ids() const override;
175 std::vector<int> boundary_nodes(const Eigen::VectorXi &vertex_to_basis) const override;
176
178 int n_quantities() const override { return m_n_quantities; };
179
181 std::vector<Tuple> get_facets() const;
183 std::vector<Tuple> get_elements() const;
184
185 // --------------------------------------------------------------------
186 // setters
187 public:
189 void set_rest_positions(const Eigen::MatrixXd &positions) override;
191 void set_positions(const Eigen::MatrixXd &positions) override;
193 void set_projection_quantities(const Eigen::MatrixXd &projection_quantities) override;
195 void set_fixed(const std::vector<bool> &fixed) override;
197 void set_boundary_ids(const BoundaryMap<int> &boundary_to_id) override;
199 void set_body_ids(const std::vector<int> &body_ids) override;
200
201 // --------------------------------------------------------------------
202 // utilities
203 public:
205 double rest_edge_length(const Tuple &e) const;
206 double deformed_edge_length(const Tuple &e) const;
207
209 VectorNd rest_edge_center(const Tuple &e) const;
210 VectorNd deformed_edge_center(const Tuple &e) const;
211
212 Eigen::VectorXd edge_adjacent_element_volumes(const Tuple &e) const;
213
215 double element_volume(const Tuple &e) const;
216
218 bool is_boundary_vertex(const Tuple &v) const;
220 bool is_body_boundary_vertex(const Tuple &v) const;
222 bool is_boundary_edge(const Tuple &e) const;
224 bool is_body_boundary_edge(const Tuple &e) const;
226 bool is_boundary_facet(const Tuple &t) const;
228 bool is_boundary_op() const;
229
231 std::vector<Tuple> boundary_facets(std::vector<int> *boundary_ids = nullptr) const;
232
234 std::array<Tuple, DIM> facet_vertices(const Tuple &t) const;
236 std::array<size_t, DIM> facet_vids(const Tuple &t) const;
237
239 std::array<Tuple, VERTICES_PER_ELEMENT> element_vertices(const Tuple &t) const;
241 std::array<size_t, VERTICES_PER_ELEMENT> element_vids(const Tuple &t) const;
242
244 void element_aabb(const Tuple &t, polyfem::VectorNd &el_min, polyfem::VectorNd &el_max) const;
245
250 std::array<size_t, VERTICES_PER_ELEMENT> orient_preserve_element_reorder(
251 const std::array<size_t, VERTICES_PER_ELEMENT> &conn, const size_t v0) const;
252
254 std::vector<Tuple> get_one_ring_elements_for_vertex(const Tuple &t) const;
255 std::vector<Tuple> get_one_ring_boundary_edges_for_vertex(const Tuple &v) const;
256 std::array<Tuple, 2> get_boundary_faces_for_edge(const Tuple &e) const;
257 std::vector<Tuple> get_one_ring_boundary_faces_for_vertex(const Tuple &v) const;
258 std::vector<Tuple> get_edges_for_elements(const std::vector<Tuple> &elements) const;
259
261 size_t facet_id(const Tuple &t) const;
262
264 size_t element_id(const Tuple &t) const;
265
267 Tuple tuple_from_element(size_t elem_id) const;
269 Tuple tuple_from_facet(size_t elem_id, int local_facet_id) const;
270
272 std::vector<Tuple> get_incident_elements_for_edge(const Tuple &t) const;
273
276 void extend_local_patch(std::vector<Tuple> &patch) const;
277
282 {
283 return e.switch_edge(*this).switch_vertex(*this);
284 }
285
290
291 protected:
292 using Operations = std::vector<std::pair<std::string, Tuple>>;
294 const std::string &op, const std::vector<Tuple> &tris) const { return {}; }
295
298 void cache_split_edge(const Tuple &e);
299
303 void cache_collapse_edge(const Tuple &e, const CollapseEdgeTo collapse_to);
304
307 void cache_swap_edge(const Tuple &e);
308
309 // NOTE: Nothing to cache for vertex smoothing
310
314
318
321
322 // NOTE: Nothing to map for vertex smoothing
323
324 // --------------------------------------------------------------------
325 // members
326 public:
328 {
330
333
335 Eigen::MatrixXd projection_quantities;
336
337 // Can the point be smoothed or moved around by operations?
338 bool fixed = false;
339 size_t partition_id = 0; // Vertices marked as fixed cannot be modified by any local operation
340
344
348 VectorNd prev_position(const int i) const
349 {
350 assert(0 <= i && i < projection_quantities.cols() / 3);
351 return rest_position + projection_quantities.col(i);
352 }
353
357 VectorNd position_i(const int i) const
358 {
359 assert(i >= 0);
360 if (i == 0)
361 return rest_position;
362 else if (i - 1 < projection_quantities.cols() / 3)
363 return prev_position(i - 1);
364 else
365 return position;
366 }
367
369 const VertexAttributes &v0,
370 const VertexAttributes &v1,
371 const CollapseEdgeTo collapse_to);
372 };
373
375 {
376 int op_depth = 0;
377 int op_attempts = 0;
378 // clang-format off
379 enum class EnergyRank { BOTTOM, MIDDLE, TOP };
380 // clang-format on
382 };
383
385 {
386 int boundary_id = -1;
387 };
388
390 {
391 int body_id = 0;
392 };
393
396 const EdgeMap<typename EdgeAttributes::EnergyRank> &contact_ranks) const;
397
401 EdgeAttributes &edge_attr(const size_t e_id);
402
406 const EdgeAttributes &edge_attr(const size_t e_id) const;
407
408 wmtk::AttributeCollection<VertexAttributes> vertex_attrs;
409 wmtk::AttributeCollection<BoundaryAttributes> boundary_attrs;
410 wmtk::AttributeCollection<ElementAttributes> element_attrs;
411
412 protected:
413 wmtk::ExecutePass<WildRemesher, EXECUTION_POLICY> executor;
416
417 // TODO: make this thread local
418 typename std::conditional<
419 std::is_same<WMTKMesh, wmtk::TriMesh>::value,
420 std::shared_ptr<TriOperationCache>,
421 std::shared_ptr<TetOperationCache>>::type op_cache;
422
423 private:
424 wmtk::AttributeCollection<EdgeAttributes> edge_attrs; // not used for tri mesh
425 };
426
429
430} // namespace polyfem::mesh
main class that contains the polyfem solver and all its state
Definition State.hpp:79
const Eigen::MatrixXd & obstacle_displacements() const
Get a reference to the collision obstacles' displacements.
Definition Remesher.hpp:133
std::unordered_map< std::array< size_t, 2 >, T, polyfem::utils::HashUnorderedArray< size_t, 2 >, polyfem::utils::EqualUnorderedArray< size_t, 2 > > EdgeMap
Map from a (sorted) edge to an integer (ID)
Definition Remesher.hpp:29
const double current_time
Current time.
Definition Remesher.hpp:219
const double starting_energy
Starting energy.
Definition Remesher.hpp:221
std::variant< EdgeMap< T >, FaceMap< T > > BoundaryMap
Definition Remesher.hpp:42
const State & state
Reference to the simulation state.
Definition Remesher.hpp:191
static constexpr int VERTICES_PER_ELEMENT
BoundaryMap< int > boundary_ids() const override
Exports boundary ids of the stored mesh.
wmtk::AttributeCollection< EdgeAttributes > edge_attrs
virtual bool collapse_edge_after(const Tuple &t) override
Definition Collapse.cpp:113
bool is_body_boundary_vertex(const Tuple &v) const
Is the given vertex tuple on the boundary of a body?
std::vector< Tuple > get_one_ring_boundary_edges_for_vertex(const Tuple &v) const
std::array< size_t, VERTICES_PER_ELEMENT > element_vids(const Tuple &t) const
Get the vertex ids of an element.
Eigen::MatrixXi elements() const override
Exports elements of the stored mesh.
void map_edge_split_boundary_attributes(const Tuple &t)
Eigen::MatrixXi edges() const override
Exports edges of the stored mesh.
Eigen::MatrixXd projection_quantities() const override
Exports projected quantities of the stored mesh.
std::conditional< std::is_same< WMTKMesh, wmtk::TriMesh >::value, std::shared_ptr< TriOperationCache >, std::shared_ptr< TetOperationCache > >::type op_cache
Eigen::MatrixXd rest_positions() const override
Exports rest positions of the stored mesh.
void init_attributes_and_connectivity(const size_t num_vertices, const Eigen::MatrixXi &elements) override
Create an internal mesh representation and associate attributes.
double deformed_edge_length(const Tuple &e) const
CollapseEdgeTo collapse_boundary_edge_to(const Tuple &e) const
Determine where to collapse an edge to.
void set_projection_quantities(const Eigen::MatrixXd &projection_quantities) override
Set projected quantities of the stored mesh.
wmtk::AttributeCollection< ElementAttributes > element_attrs
void write_edge_ranks_mesh(const EdgeMap< typename EdgeAttributes::EnergyRank > &elastic_ranks, const EdgeMap< typename EdgeAttributes::EnergyRank > &contact_ranks) const
Eigen::MatrixXi boundary_faces() const override
Exports boundary faces of the stored mesh.
size_t facet_id(const Tuple &t) const
Get the id of a facet (edge for triangle, triangle for tetrahedra)
virtual Operations renew_neighbor_tuples(const std::string &op, const std::vector< Tuple > &tris) const
bool is_boundary_vertex(const Tuple &v) const
Is the given vertex tuple on the boundary of the mesh?
std::vector< Tuple > boundary_facets(std::vector< int > *boundary_ids=nullptr) const
Get the boundary facets of the mesh.
std::array< Tuple, DIM > facet_vertices(const Tuple &t) const
Get the vertex tuples of a facet.
std::vector< std::pair< std::string, Tuple > > Operations
void set_body_ids(const std::vector< int > &body_ids) override
Set the body IDs of all elements.
wmtk::ExecutePass< WildRemesher, EXECUTION_POLICY > executor
wmtk::AttributeCollection< BoundaryAttributes > boundary_attrs
Tuple tuple_from_facet(size_t elem_id, int local_facet_id) const
Get a tuple of an element with a local facet.
virtual void init(const Eigen::MatrixXd &rest_positions, const Eigen::MatrixXd &positions, const Eigen::MatrixXi &elements, const Eigen::MatrixXd &projection_quantities, const BoundaryMap< int > &boundary_to_id, const std::vector< int > &body_ids, const EdgeMap< double > &elastic_energy, const EdgeMap< double > &contact_energy) override
Initialize the mesh.
std::array< size_t, DIM > facet_vids(const Tuple &t) const
Get the vertex ids of a facet.
bool is_body_boundary_edge(const Tuple &e) const
Is the given edge tuple on the boundary of a body?
std::array< Tuple, VERTICES_PER_ELEMENT > element_vertices(const Tuple &t) const
Get the vertex tuples of an element.
void set_rest_positions(const Eigen::MatrixXd &positions) override
Set rest positions of the stored mesh.
int n_quantities() const override
Number of projection quantities (not including the position)
virtual bool smooth_before(const Tuple &t) override
Definition Smooth.cpp:162
typename WMTKMesh::Tuple Tuple
void set_positions(const Eigen::MatrixXd &positions) override
Set deformed positions of the stored mesh.
bool is_rest_inverted(const Tuple &loc) const
Check if a triangle's rest shape is inverted.
wmtk::AttributeCollection< VertexAttributes > vertex_attrs
virtual void smooth_vertices()
Definition Smooth.cpp:296
void set_boundary_ids(const BoundaryMap< int > &boundary_to_id) override
Set the boundary IDs of all edges.
std::vector< Tuple > get_edges_for_elements(const std::vector< Tuple > &elements) const
bool is_boundary_facet(const Tuple &t) const
Is the given tuple on the boundary of the mesh?
std::array< size_t, VERTICES_PER_ELEMENT > orient_preserve_element_reorder(const std::array< size_t, VERTICES_PER_ELEMENT > &conn, const size_t v0) const
Reorder the element vertices so that the first vertex is v0.
bool execute() override
Execute the remeshing.
Definition Execute.cpp:13
double rest_edge_length(const Tuple &e) const
Compute the length of an edge.
bool is_inverted(const Tuple &loc) const
Check if a triangle's rest and deformed shapes are inverted.
virtual ~WildRemesher()=default
Eigen::MatrixXd positions() const override
Exports displacements of the stored mesh.
VectorNd rest_edge_center(const Tuple &e) const
Compute the center of the edge.
std::vector< Tuple > get_one_ring_elements_for_vertex(const Tuple &t) const
Get the one ring of elements around a vertex.
std::array< Tuple, 2 > get_boundary_faces_for_edge(const Tuple &e) const
static constexpr wmtk::ExecutionPolicy EXECUTION_POLICY
Current execuation policy (sequencial or parallel)
static constexpr int DIM
std::vector< int > body_ids() const override
Exports body ids of the stored mesh.
void element_aabb(const Tuple &t, polyfem::VectorNd &el_min, polyfem::VectorNd &el_max) const
Get a AABB for an element.
std::vector< int > boundary_nodes(const Eigen::VectorXi &vertex_to_basis) const override
Get the boundary nodes of the stored mesh.
bool is_boundary_edge(const Tuple &e) const
Is the given edge tuple on the boundary of the mesh?
void map_edge_collapse_boundary_attributes(const Tuple &t)
void cache_split_edge(const Tuple &e)
Cache the split edge operation.
Definition Split.cpp:6
Eigen::VectorXd edge_adjacent_element_volumes(const Tuple &e) const
std::vector< Tuple > get_facets() const
Get a vector of all facets (edges or triangles)
int dim() const override
Dimension of the mesh.
virtual void collapse_edges()=0
Tuple tuple_from_element(size_t elem_id) const
Get a tuple of an element.
std::vector< Tuple > get_incident_elements_for_edge(const Tuple &t) const
Get the incident elements for an edge.
virtual void split_edges()=0
EdgeAttributes & edge_attr(const size_t e_id)
Get a reference to an edge's attributes.
Eigen::MatrixXi boundary_edges() const override
Exports boundary edges of the stored mesh.
void map_edge_swap_element_attributes(const Tuple &t)
static constexpr int FACETS_PER_ELEMENT
void map_edge_collapse_vertex_attributes(const Tuple &t)
void extend_local_patch(std::vector< Tuple > &patch) const
Extend the local patch by including neighboring elements.
virtual bool swap_edge_before(const Tuple &t) override
Definition Swap.cpp:17
std::vector< Tuple > get_elements() const
Get a vector of all elements (triangles or tetrahedra)
size_t element_id(const Tuple &t) const
Get the id of an element (triangle or tetrahedra)
void map_edge_swap_edge_attributes(const Tuple &t)
void map_edge_collapse_edge_attributes(const Tuple &t)
Eigen::Matrix< double, DIM, 1 > VectorNd
double element_volume(const Tuple &e) const
Compute the volume (area) of an tetrahedron (triangle) element.
bool is_boundary_op() const
Is the currently cached operation a boundary operation?
virtual bool split_edge_after(const Tuple &t) override
Definition Split.cpp:74
void map_edge_split_edge_attributes(const Tuple &t)
void set_fixed(const std::vector< bool > &fixed) override
Set if a vertex is fixed.
virtual bool smooth_after(const Tuple &t) override
Definition Smooth.cpp:192
virtual bool split_edge_before(const Tuple &t) override
Definition Split.cpp:12
void cache_swap_edge(const Tuple &e)
Cache the edge swap operation.
Definition Swap.cpp:8
void map_edge_split_element_attributes(const Tuple &t)
std::vector< Tuple > get_one_ring_boundary_faces_for_vertex(const Tuple &v) const
Tuple opposite_vertex_on_face(const Tuple &e) const
Get the opposite vertex on a face.
const EdgeAttributes & edge_attr(const size_t e_id) const
Get a const reference to an edge's attributes.
bool invariants(const std::vector< Tuple > &new_tris) override
Check if invariants are satisfied.
Eigen::MatrixXd displacements() const override
Exports positions of the stored mesh.
VectorNd deformed_edge_center(const Tuple &e) const
WildRemesher< WMTKMesh > This
static constexpr int EDGES_PER_ELEMENT
virtual bool swap_edge_after(const Tuple &t) override
void cache_collapse_edge(const Tuple &e, const CollapseEdgeTo collapse_to)
Cache the edge collapse operation.
Definition Collapse.cpp:11
virtual bool collapse_edge_before(const Tuple &t) override
Definition Collapse.cpp:18
WildTetRemesher::Tuple Tuple
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > VectorNd
Definition Types.hpp:9
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:71
Eigen::MatrixXd projection_quantities
Quantities to be projected (dim × n_quantities)
static VertexAttributes edge_collapse(const VertexAttributes &v0, const VertexAttributes &v1, const CollapseEdgeTo collapse_to)
Definition Collapse.cpp:267
VectorNd prev_position(const int i) const
Previous position of the vertex.
VectorNd position_i(const int i) const
Get the position of the vertex at different times.
VectorNd displacement() const
Current displacement from rest position to current position.
WildRemesher< WMTKMesh >::VectorNd VectorNd