Wildmeshing Toolkit
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
wmtk::TetOptimizerMesh Class Referenceabstract

What tetwild and simwild's 3D mesh share. More...

#include <TetOptimizerMesh.h>

Inheritance diagram for wmtk::TetOptimizerMesh:
wmtk::TetMesh wmtk::RationalPositions wmtk::components::simwild::SimWildMesh wmtk::components::tetwild::TetWildMesh wmtk::components::topological_offset::TopoOffsetTetMesh wmtk::components::manifold_extraction::ManExtractTetMesh

Classes

struct  CoarsenScratch
 Per-thread buffers for the coarsening composite, so it allocates nothing. More...
 
struct  CoarsenStats
 What coarsen_mesh() achieved, for the run report. Zeroed when the pass is off. More...
 
struct  CollapseInfoCache
 
struct  SplitInfoCache
 
struct  SwapInfoCache
 
struct  VertexAttributes
 

Public Types

using FaceAttributes = wmtk::SurfaceTagAttributes
 
using VertAttCol = AttributeCollection< VertexAttributes >
 
using FaceAttCol = AttributeCollection< FaceAttributes >
 
using SurfaceTopoSignature = wmtk::utils::SurfaceTopoSignature
 
- Public Types inherited from wmtk::TetMesh
template<typename T >
using vector = std::vector< T >
 
using VertexMutex = wmtk::threading::VertexMutex
 

Public Member Functions

bool is_force_split_edge (const size_t v1, const size_t v2) const
 
 TetOptimizerMesh (OptimizerParameters &params, std::shared_ptr< SampleEnvelope > env)
 
virtual double cell_quality (const size_t tid) const =0
 The quality of cell tid, and how to write it.
 
virtual void set_cell_quality (const size_t tid, const double q)=0
 
virtual double quality_rel (const size_t tid) const
 A cell's quality relative to the quality it is required to reach; <= 1 means it meets it.
 
void compute_vertex_partition ()
 
void compute_vertex_partition_morton ()
 
size_t get_partition_id (const Tuple &loc) const
 
double get_length2 (const Tuple &l) const
 
bool is_inverted (const std::array< size_t, 4 > &vs) const
 
bool is_inverted (const Tuple &loc) const
 
bool is_inverted_f (const Tuple &loc) const
 Inversion check using only the double positions.
 
double get_quality (const std::array< size_t, 4 > &vs) const
 
double get_quality (const Tuple &loc) const
 
std::tuple< double, double > get_max_avg_energy ()
 
void mesh_improvement (int max_its=80)
 
std::tuple< double, double > local_operations (const std::array< int, 4 > &ops, bool collapse_limit_length=true)
 
bool round (const Tuple &v)
 Round a vertex position to floating point, if that inverts no incident tet.
 
bool is_edge_on_surface (const Tuple &loc)
 
bool is_edge_on_bbox (const Tuple &loc)
 
virtual bool is_open_boundary_edge (const Tuple &e)
 Whether edge e lies on the boundary of the tracked surface.
 
int edge_incident_surface_face_count (const Tuple &e)
 How many of the faces incident to edge e are on the tracked surface.
 
virtual std::shared_ptr< SampleEnvelopesurface_envelope_for_face (const std::array< size_t, 3 > &vids) const
 Envelope the tracked-surface triangle vids must stay inside.
 
bool surface_triangle_is_outside (const size_t a, const size_t b, const size_t c) const
 
bool vertex_is_on_surface (const size_t vid) const override
 Is a vertex part of the substructure.
 
bool face_is_on_surface (const size_t fid) const override
 Is a face part of the substructure.
 
size_t get_order_of_vertex (const size_t vid) const override
 Get the order of a vertex.
 
std::vector< std::array< size_t, 3 > > get_faces_by_condition (std::function< bool(const FaceAttributes &)> cond) const
 
void output_faces (std::string file, std::function< bool(const FaceAttributes &)> cond)
 
void gradation_smooth_sizing (double grade, const std::vector< size_t > &seeds)
 Grade the refined sizing region into its surroundings (monotone, only lowers).
 
double active_quality_threshold () const
 Cell-quality threshold above which a tet is "active" (worth operating on) for the skip-good-regions filter.
 
virtual std::vector< size_t > active_vertices () const
 
void split_all_edges ()
 
bool split_edge_before (const Tuple &t) override
 User specified preparations and desideratas for an edge split before changing the connectivity.
 
bool split_edge_after (const Tuple &loc) override
 This function computes the attributes for the added simplices. User specified modifications and desideratas for after an edge split.
 
void collapse_all_edges (bool is_limit_length=true)
 
bool collapse_edge_before (const Tuple &t) override
 User specified preparations and desideratas for an edge collapse before changing the connectivity.
 
bool collapse_edge_after (const Tuple &t) override
 User specified modifications and desideratas for after an edge collapse.
 
size_t coarsen_mesh ()
 Coarsen the mesh without letting the max energy rise.
 
bool coarsen_collapse_edge (const Tuple &e, std::vector< Tuple > &new_tets)
 One collapse under the coarsening rules, outside a coarsening pass.
 
size_t swap_all_edges_32 ()
 
bool swap_edge_before (const Tuple &t) override
 User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity.
 
bool swap_edge_after (const Tuple &t) override
 User specified modifications and desideratas for after a 3-2 edge swap.
 
size_t swap_all_edges_44 ()
 
bool swap_edge_44_before (const Tuple &t) override
 User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity.
 
bool swap_edge_44_accept_case (const std::array< size_t, 2 > &new_edge) override
 Filter which of the 4-4 orientations may be chosen.
 
bool swap_edge_44_after (const Tuple &t) override
 User specified modifications and desideratas for after a 4-4 edge swap.
 
size_t swap_all_edges_56 ()
 
bool swap_edge_56_before (const Tuple &t) override
 User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity.
 
bool swap_edge_56_accept_case (const std::array< size_t, 3 > &new_face) override
 Filter which of the 5-6 orientations may be chosen.
 
bool swap_edge_56_after (const Tuple &t) override
 User specified modifications and desideratas for after a 5-6 edge swap.
 
size_t swap_all_faces ()
 
bool swap_face_before (const Tuple &t) override
 User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry.
 
bool swap_face_after (const Tuple &t) override
 User specified modifications and desideratas for after a 2-3 face swap.
 
size_t swap_all_edges_all ()
 
bool prepare_surface_flip (const Tuple &t, const std::vector< size_t > &incident_tets)
 
SurfaceTopoSignature surface_topology_signature () const
 
void warn_if_surface_topology_changed (const SurfaceTopoSignature &before, const char *where) const
 
double swap_edge_44_energy (const std::vector< std::array< size_t, 4 > > &tets, const int op_case) override
 User specified energy to decide which of the 4 possible orientations should be chosen.
 
double swap_edge_56_energy (const std::vector< std::array< size_t, 4 > > &tets, const int op_case) override
 User specified energy to decide which of the 5 possible orientations should be chosen.
 
virtual std::shared_ptr< SampleEnvelopesmoothing_containment_envelope (const size_t vid) const
 Envelope the resulting surface triangles are checked against.
 
virtual std::shared_ptr< SampleEnvelopesmoothing_energy_envelope (const size_t vid) const =0
 
bool smooth_before (const Tuple &t) override
 User specified preparations and desideratas for smoothing a vertex.
 
bool smooth_after (const Tuple &t) override
 User specified modifications and desideratas for after smoothing a vertex.
 
void smooth_all_vertices (const size_t n_iters=1)
 
bool invariants (const std::vector< Tuple > &t) override
 
- Public Member Functions inherited from wmtk::TetMesh
size_t vert_capacity () const
 get the current largest global vid
 
size_t tet_capacity () const
 get the current largest global tid
 
size_t vertex_size () const
 get the number of unremoved verticies
 
size_t tet_size () const
 get the number of unremoved tets
 
void init (size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets)
 
void init_with_isolated_vertices (size_t n_vertices, const std::vector< std::array< size_t, 4 > > &tets)
 
void init (const MatrixXi &T)
 Generate the connectivity of the mesh from an IGL-style T matrix.
 
bool split_edge (const Tuple &t, std::vector< Tuple > &new_tets)
 
virtual bool collapse_edge (const Tuple &t, std::vector< Tuple > &new_tets)
 
bool link_condition (const Tuple &t)
 
bool collapse_edge_conn (const Tuple &loc0, size_t &v1_id, Tuple &new_loc, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids_copy, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
 
bool collapse_edge_check_topology (const std::vector< size_t > &new_tet_id)
 Check topology after collapse connectivity change. This is a sanity check and should not be necessary.
 
void collapse_edge_rollback (size_t &v1_id, std::map< size_t, wmtk::TetMesh::VertexConnectivity > &rollback_vert_conn, std::vector< size_t > &n1_t_ids, std::vector< size_t > &new_tet_id, std::vector< TetrahedronConnectivity > &old_tets)
 
bool swap_edge_56 (const Tuple &t, std::vector< Tuple > &new_tets)
 
bool swap_edge_44 (const Tuple &t, std::vector< Tuple > &new_tets)
 
bool swap_edge (const Tuple &t, std::vector< Tuple > &new_tets)
 3-2 edge swap
 
bool swap_face (const Tuple &t, std::vector< Tuple > &new_tets)
 2-3 face swap
 
bool smooth_vertex (const Tuple &t)
 
bool split_tet (const Tuple &t, std::vector< Tuple > &new_tets)
 Split a tet in 4 tets.
 
bool split_face (const Tuple &t, std::vector< Tuple > &new_tets)
 Split a face in 3 faces.
 
void triangle_insertion (const std::vector< Tuple > &intersected_tets, const std::vector< Tuple > &intersected_edges, std::vector< size_t > &new_edge_vids, std::vector< size_t > &new_center_vids, std::vector< std::array< size_t, 4 > > &center_split_tets)
 Insert a triangle into a tetmesh, with known intersection information.
 
bool insert_point (const Tuple &t, std::vector< Tuple > &new_tets)
 Insert a point into a tetmesh inside a tet. In general position, this split a tet into 4. In face position, split two tets. In edge position, In point position, do nothing.
 
virtual bool insert_point_before (const Tuple &t)
 
virtual bool insert_point_after (std::vector< Tuple > &new_tets)
 
void consolidate_mesh ()
 cleans up the deleted vertices or tetrahedra, fixes the corresponding indices, and reset the version number. WARNING: it invalidates all tuples!
 
std::vector< Tupleget_edges () const
 
std::vector< Tupleget_faces () const
 
std::vector< Tupleget_vertices () const
 
std::vector< Tupleget_tets () const
 
virtual void for_each_face (const std::function< void(const TetMesh::Tuple &)> &)
 looping through all the unique edges and perform the given function
 
void set_preallocation_factor (double factor)
 Preallocation factor: init/consolidate reserve capacity = max(floor, ceil(factor * live_count)) so operations can grab fresh slots without resizing the storage. When a pass exhausts the reserved capacity the affected operations fail (and are retried later after a consolidate). Tune per application (e.g. from JSON); values < 1 are clamped to 1.
 
double preallocation_factor () const
 
long request_tet_slots (size_t n)
 
long request_vert_slots (size_t n)
 
void ensure_free_tet_capacity (size_t extra)
 
void ensure_free_vert_capacity (size_t extra)
 
Tuple tuple_from_edge (size_t tid, int local_eid) const
 get a Tuple from global tetra index and local edge index (from 0-5).
 
Tuple tuple_from_edge (const std::array< size_t, 2 > &vids) const
 get a Tuple from global vids of the 2 end of an edge
 
Tuple tuple_from_face (size_t tid, int local_fid) const
 get a Tuple from global tetra index and local face index (from 0-3).
 
std::tuple< Tuple, size_t > tuple_from_face (const std::array< size_t, 3 > &vids) const
 get a Tuple and the global face index from global vertex index of the face.
 
std::optional< std::tuple< Tuple, size_t > > try_tuple_from_face (const std::array< size_t, 3 > &vids) const
 tuple_from_face for callers where a missing face is an answer, not a bug.
 
size_t lowest_common_tet (size_t v0_id, size_t v1_id, size_t v2_id) const
 Lowest tet id incident to all three vertices, or size_t(-1) if there is none.
 
size_t vertex_valence (const size_t vid) const
 Number of tets incident to a vertex, in O(1).
 
std::tuple< Tuple, size_t > tuple_from_face (const simplex::Face &f) const
 
Tuple tuple_from_vertex (size_t vid) const
 get a Tuple from global vertex index
 
Tuple tuple_from_tet (size_t tid) const
 get a Tuple from global tetra index
 
Tuple tuple_from_vids (size_t vid0, size_t vid1, size_t vid2, size_t vid3) const
 Get a Tuple from global vertex IDs.
 
simplex::Tet simplex_from_tet (const Tuple &t) const
 
simplex::Tet simplex_from_tet (const size_t tid) const
 
simplex::Face simplex_from_face (const Tuple &t) const
 
simplex::Edge simplex_from_edge (const Tuple &t) const
 
Tuple switch_vertex (const Tuple &t) const
 wrapper function from Tuple::switch_vertex
 
Tuple switch_edge (const Tuple &t) const
 wrapper function from Tuple::switch_edge
 
Tuple switch_face (const Tuple &t) const
 wrapper function from Tuple::switch_face
 
std::optional< Tupleswitch_tetrahedron (const Tuple &t) const
 wrapper function from Tuple::switch_tetrahedron
 
std::vector< Tupleget_one_ring_tets_for_vertex (const Tuple &t) const
 Get the one ring tets for a vertex.
 
const std::vector< size_t > & get_one_ring_tids_for_vertex (const Tuple &t) const
 Get the one ring tids for vertex.
 
const std::vector< size_t > & get_one_ring_tids_for_vertex (const size_t vid) const
 
std::vector< Tupleget_one_ring_vertices_for_vertex (const Tuple &t) const
 Get the one ring vertices for a vertex.
 
std::vector< size_t > get_one_ring_vids_for_vertex (size_t vid, std::vector< size_t > &cache)
 Get the one ring vids for vertex.
 
std::vector< size_t > get_one_ring_vids_for_vertex (size_t vid) const
 Get the one ring vids for vertex.
 
std::vector< size_t > get_one_ring_vids_for_vertex_adj (size_t vid) const
 Duplicate of the function TetMesh::get_one_ring_vids_for_vertex.
 
std::vector< size_t > get_one_ring_vids_for_vertex_adj (size_t vid, std::vector< size_t > &cache)
 Duplicate of the function TetMesh::get_one_ring_vids_for_vertex.
 
std::vector< Tupleget_incident_tets_for_edge (const Tuple &t) const
 Get the incident tets for edge.
 
std::vector< Tupleget_incident_tets_for_edge (const size_t vid0, const size_t vid1) const
 
std::vector< size_t > get_incident_tids_for_edge (const Tuple &t) const
 
std::vector< size_t > get_incident_tids_for_edge (const size_t vid0, const size_t vid1) const
 
std::vector< Tupleget_one_ring_tets_for_edge (const Tuple &t) const
 Get the one ring tets for edge.
 
std::vector< std::array< size_t, 3 > > vertex_adjacent_boundary_faces (const Tuple &t) const
 
std::array< Tuple, 4 > oriented_tet_vertices (const Tuple &t) const
 
std::array< size_t, 4 > oriented_tet_vids (const Tuple &t) const
 
std::array< size_t, 4 > oriented_tet_vids (const size_t tid) const
 
std::array< Tuple, 3 > get_face_vertices (const Tuple &t) const
 Get the 3 vertices of a face represented by Tuple.
 
std::array< size_t, 3 > get_face_vids (const Tuple &t) const
 
std::array< Tuple, 6 > tet_edges (const Tuple &t) const
 get the 6 edges of a tet represented by Tuples
 
void check_tuple_validity (const Tuple &t) const
 
bool check_mesh_connectivity_validity () const
 checks the validity of the connectivity of the mesh. Including the validity of each Tuple
 
void remove_tets_by_ids (const std::vector< size_t > &tids)
 remove the tetrahedrons in the mesh that have given tet ids
 
void start_protect_attributes ()
 
void release_protect_attributes ()
 
void rollback_protected_attributes ()
 
int release_vertex_mutex_in_stack ()
 
int release_vertex_mutex_to (size_t mark)
 Release the mutexes taken since the release stack held mark entries.
 
bool try_set_vertex_mutex_n_ring (const Tuple &v, int threadid, int n)
 Lock every vertex within graph distance n of v, the seed included.
 
bool try_set_vertex_mutex_n_ring (size_t vid, int threadid, int n)
 
bool try_set_edge_mutex_n_ring (const Tuple &e, int threadid, int n)
 try_set_vertex_mutex_n_ring seeded from both ends of an edge.
 
bool try_set_face_mutex_n_ring (size_t v1, size_t v2, size_t v3, int threadid, int n)
 try_set_vertex_mutex_n_ring seeded from the three vertices of a face.
 
void for_each_edge (const std::function< void(const TetMesh::Tuple &)> &)
 perform the given function for each edge
 
void for_each_vertex (const std::function< void(const TetMesh::Tuple &)> &)
 perform the given function for each vertex
 
void for_each_tetra (const std::function< void(const TetMesh::Tuple &)> &)
 perform the given function for each tet
 
simplex::SimplexCollection get_surface_faces_for_vertex (const size_t vid) const
 Get all faces on the surface that are incident to vid.
 
simplex::SimplexCollection get_surface_faces_for_edge (const std::array< size_t, 2 > &vids) const
 Get all faces on the surface that are incident to the edge.
 
size_t get_num_surface_faces_for_edge (const std::array< size_t, 2 > &vids) const
 Get the number of surface faces incident to the edge.
 
size_t compute_vertex_order (const size_t vid) const
 Compute the vertex order for a single vertex.
 
size_t get_order_of_edge (const std::array< size_t, 2 > &vids) const
 Compute the order of an edge.
 
bool substructure_link_condition (const Tuple &e_tuple) const
 Link condition that also considers substructures.
 
bool try_set_vertex_mutex_two_ring (const Tuple &v, int threadid)
 Lock v's one-ring and, partially, its two-ring. See the note above.
 
bool try_set_vertex_mutex_two_ring_vid (const Tuple &v, int threadid)
 try_set_vertex_mutex_two_ring reached through vids rather than Tuples.
 
bool try_set_vertex_mutex_two_ring_vid (size_t v, int threadid)
 try_set_vertex_mutex_two_ring reached through vids rather than Tuples.
 
bool try_set_edge_mutex_two_ring (const Tuple &e, int threadid=0)
 Lock the edge's one-ring and, partially, its two-ring. See the note above.
 
bool try_set_face_mutex_two_ring (const Tuple &f, int threadid=0)
 Lock the face's one-ring and, partially, its two-ring. See the note above.
 
bool try_set_face_mutex_two_ring (const Tuple &v1, const Tuple &v2, const Tuple &v3, int threadid=0)
 Lock the face's one-ring and, partially, its two-ring. See the note above.
 
bool try_set_face_mutex_two_ring (size_t v1, size_t v2, size_t v3, int threadid=0)
 Lock the face's one-ring and, partially, its two-ring. See the note above.
 
bool try_set_vertex_mutex_one_ring (const Tuple &v, int threadid=0)
 Lock v and its one-ring. Complete, unlike the two-ring family.
 
size_t cell_capacity () const
 
Tuple tuple_from_cell (size_t cid) const
 
- Public Member Functions inherited from wmtk::RationalPositions
size_t round_all_vertices ()
 Try to round every un-rounded vertex; returns the number reclaimed.
 
bool round_and_check_all_rounded ()
 Run the sweep, then report whether the mesh is now fully rounded.
 

Public Attributes

VertAttCol m_vertex_attribute
 
FaceAttCol m_face_attribute
 
AttributeContainerGroup m_vertex_attr_group
 What p_vertex_attrs points at, so a derived class can register more.
 
AttributeContainerGroup m_face_attr_group
 What p_face_attrs points at, so a derived class can register more.
 
OptimizerParametersm_params
 
std::shared_ptr< SampleEnvelopem_envelope
 Surface envelope: what a surface vertex is pulled toward and checked against.
 
double m_s_amips = 1.
 
double m_s_envelope = -1.
 
double time_env = 0.0
 
igl::Timer isout_timer
 
wmtk::threading::enumerable_thread_specific< std::unique_ptr< polysolve::nonlinear::Solver > > m_solver
 Per-thread Newton solver for smoothing; created on first use.
 
optimization::SmoothRejectCounters m_smooth_rejects
 Why smoothing attempts were refused, reported once per pass.
 
bool m_collapse_limit_length = true
 
std::set< simplex::Edgem_force_split_edges
 
size_t m_force_split_count = 0
 Force-splits taken in the current split pass. Diagnostic only.
 
std::unique_ptr< std::atomic< int >[]> m_high_valence_claim
 Per-pass claims for the shared high-valence split gate.
 
size_t m_high_valence_claim_size = 0
 
std::atomic< size_t > m_high_valence_rejects = 0
 
int m_iterations_used = 0
 Shared TetWild/SimWild outer optimization schedule.
 
int m_debug_print_counter = 0
 
CoarsenStats m_coarsen_stats
 
std::atomic< int > cnt_swap = 0
 
std::atomic< int > cnt_surface_swap = 0
 
std::atomic< int > cnt_surface_swap_32 = 0
 
std::atomic< int > cnt_surface_swap_44 = 0
 
std::atomic< int > cnt_surface_swap_56 = 0
 
- Public Attributes inherited from wmtk::TetMesh
AbstractAttributeContainerp_vertex_attrs = nullptr
 
AbstractAttributeContainerp_edge_attrs = nullptr
 
AbstractAttributeContainerp_face_attrs = nullptr
 
AbstractAttributeContainerp_tet_attrs = nullptr
 
bool m_collapse_check_link_condition = true
 
bool m_collapse_check_topology = false
 
bool m_collapse_check_manifold = true
 
wmtk::threading::enumerable_thread_specific< std::vector< size_t > > mutex_release_stack
 
wmtk::threading::enumerable_thread_specific< std::vector< size_t > > get_one_ring_cache
 
int NUM_THREADS = 0
 

Static Public Attributes

static constexpr double MAX_ENERGY = 1e50
 The sentinel get_quality returns for an element AMIPS cannot score.
 
- Static Public Attributes inherited from wmtk::TetMesh
static constexpr int EDGES_PER_CELL = 6
 
static constexpr int FACES_PER_CELL = 4
 

Protected Member Functions

std::vector< size_t > all_vertex_ids () const override
 Every live vertex, in the mesh's own iteration order.
 
bool vertex_is_rounded (const size_t vid) const override
 Whether this vertex's double position is currently trusted.
 
bool round_vertex (const size_t vid) override
 
virtual std::tuple< double, double > optimization_quality_stats ()
 
virtual double optimization_stop_metric () const
 
virtual size_t refine_sizing_around_worst (double max_metric)=0
 
virtual void write_optimization_debug_output (const std::string &path)=0
 
virtual void optimization_sanity_checks_extra ()
 
virtual bool optimization_stop_at_float () const
 
virtual bool collapse_before_vertex (size_t, size_t, double)
 
virtual bool collapse_quality_allowed (size_t v1, double quality, double ring_max) const
 
virtual bool collapse_is_order_2_edge (const std::array< size_t, 2 > &)
 
virtual bool collapse_after_connectivity (size_t, size_t, const std::vector< std::array< size_t, 2 > > &)
 
virtual void collapse_after_vertex (size_t, size_t)
 
virtual bool split_before_cells (const Tuple &, const std::vector< Tuple > &)
 Cache application cell data before a split. TetWild needs none; SimWild caches tags.
 
virtual bool split_after_cells (size_t, size_t, size_t, const std::vector< Tuple > &)
 Restore application cell data on the children made by a split.
 
virtual bool split_adjust_position (size_t, const std::vector< Tuple > &)
 
virtual void split_after_vertex (size_t, bool)
 Application metadata not represented by the shared vertex attributes.
 
virtual bool allow_surface_swap () const =0
 
virtual bool check_surface_topology () const =0
 
virtual bool swap_before_interior (const std::vector< size_t > &)
 Application data attached to the old cells. TetWild has none; SimWild caches tags.
 
virtual bool swap_before_surface (const std::vector< size_t > &, size_t, size_t, size_t, size_t)
 
virtual bool swap_after_cells (const std::vector< size_t > &, bool)
 Propagate application data to the cells made by a successful topological swap.
 
- Protected Member Functions inherited from wmtk::TetMesh
virtual bool triangle_insertion_before (const std::vector< Tuple > &faces)
 
virtual bool triangle_insertion_after (const std::vector< std::vector< Tuple > > &)
 
virtual bool split_face_before (const Tuple &t)
 User specified preparations and desideratas for a face split before changing the connectivity.
 
virtual bool split_face_after (const Tuple &t)
 Compute the attributes for the added simplices.
 
virtual bool split_tet_before (const Tuple &t)
 User specified preparations and desideratas for a tet split before changing the connectivity.
 
virtual bool split_tet_after (const Tuple &t)
 Compute the attributes for the added simplices.
 
void resize_vertex_mutex (size_t v)
 

Protected Attributes

wmtk::threading::enumerable_thread_specific< SwapInfoCacheswap_cache
 
wmtk::threading::enumerable_thread_specific< SplitInfoCachesplit_cache
 
wmtk::threading::enumerable_thread_specific< CollapseInfoCachecollapse_cache
 
bool m_coarsen_mode = false
 Set for the duration of coarsen_mesh(); read-only while a pass is running.
 
- Protected Attributes inherited from wmtk::RationalPositions
std::atomic< bool > m_all_rounded = false
 True when every vertex is known to be rounded.
 

Private Member Functions

const std::vector< size_t > & collect_vertex_ball (const size_t *seeds, size_t n_seeds, int n, CoarsenScratch &scr) const
 Vertices within n edges of seeds, in BFS order. Uses coarsen_scratch.
 
double region_max_quality_rel (const std::vector< size_t > &vids) const
 
bool smooth_vertex_reversible (size_t vid, CoarsenScratch &scr)
 One smoothing attempt on vid, restoring everything it wrote if it is rejected.
 
size_t collapse_all_edges_impl (bool is_limit_length, int lock_ring, size_t max_passes=0)
 

Private Attributes

wmtk::threading::enumerable_thread_specific< CoarsenScratchcoarsen_scratch
 

Detailed Description

What tetwild and simwild's 3D mesh share.

Seeded by MOVING tetwild's implementation here, not by designing an abstraction: tetwild is the more heavily measured of the two, so the move leaves it byte-identical and confines any output change to the commit where simwild adopts the base.

The 2D counterpart is wmtk::TriOptimizerMesh. The two are deliberately NOT unified with each other – see that class for why.

Cell attributes stay per-application. tetwild's tets carry winding numbers and a flood-fill id, simwild's carry a CellTag set, and an AttributeCollection member cannot change type in a derived class. The base therefore reaches the one field it needs – the quality – through cell_quality()/set_cell_quality(). This keeps the shared pass, swap and smoothing implementations independent of the derived cell-attribute layout; the virtual dispatch is negligible beside their geometric predicates and energy evaluations.

Member Function Documentation

◆ active_quality_threshold()

double wmtk::TetOptimizerMesh::active_quality_threshold ( ) const
inline

Cell-quality threshold above which a tet is "active" (worth operating on) for the skip-good-regions filter.

The quality stores AMIPS^3 and the energy is its cube root, so a tet is active when its energy is at least skip_good_regions_margin * stop_energy, i.e. the quality is at least (margin * stop_energy)^3.

◆ active_vertices()

std::vector< size_t > wmtk::TetOptimizerMesh::active_vertices ( ) const
virtual

vids of the vertices incident to at least one "active" cell, for the skip-good-regions filter.

Reimplemented in wmtk::components::simwild::SimWildMesh.

◆ all_vertex_ids()

std::vector< size_t > wmtk::TetOptimizerMesh::all_vertex_ids ( ) const
overrideprotectedvirtual

Every live vertex, in the mesh's own iteration order.

Implements wmtk::RationalPositions.

◆ allow_surface_swap()

virtual bool wmtk::TetOptimizerMesh::allow_surface_swap ( ) const
protectedpure virtual

◆ cell_quality()

virtual double wmtk::TetOptimizerMesh::cell_quality ( const size_t  tid) const
pure virtual

The quality of cell tid, and how to write it.

The cell attribute types differ between the applications, so the base reaches the one field it shares through these. Both are AMIPS^3; see MAX_ENERGY. Topological operations and smoothing use the accessors so the shared algorithms remain independent of each application's cell-attribute type.

Implemented in wmtk::components::simwild::SimWildMesh, wmtk::components::tetwild::TetWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ coarsen_collapse_edge()

bool wmtk::TetOptimizerMesh::coarsen_collapse_edge ( const Tuple e,
std::vector< Tuple > &  new_tets 
)

One collapse under the coarsening rules, outside a coarsening pass.

The pass sets the mode once and leaves it set for its whole duration, because every worker reads it; this is the single-operation form, for callers that want one and are not sharing the mesh with other threads.

◆ coarsen_mesh()

size_t wmtk::TetOptimizerMesh::coarsen_mesh ( )

Coarsen the mesh without letting the max energy rise.

The 3D twin of TriOptimizerMesh::coarsen_mesh; see OptimizerParameters::coarsen_pass for what makes the collapse in this pass different, and collapse_edge_after for how it is undone when it does not pay off. A no-op when m_params.coarsen_pass is false.

Returns
the number of collapses accepted across all rounds.

◆ collapse_before_vertex()

virtual bool wmtk::TetOptimizerMesh::collapse_before_vertex ( size_t  ,
size_t  ,
double   
)
inlineprotectedvirtual

Non-const: an override may cache what it measured before the collapse so its after counterpart can tell a regression from a defect that was already there.

Reimplemented in wmtk::components::simwild::SimWildMesh, wmtk::components::tetwild::TetWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ collapse_edge_after()

bool wmtk::TetOptimizerMesh::collapse_edge_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after an edge collapse.

Parameters
tedge Tuple that's collapsed
Returns
true if the modification succeed

Reimplemented from wmtk::TetMesh.

◆ collapse_edge_before()

bool wmtk::TetOptimizerMesh::collapse_edge_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for an edge collapse before changing the connectivity.

Parameters
tedge Tuple to be collapsed
Returns
true is the preparation succeed

check if on bbox/surface/boundary

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ edge_incident_surface_face_count()

int wmtk::TetOptimizerMesh::edge_incident_surface_face_count ( const Tuple e)

How many of the faces incident to edge e are on the tracked surface.

Unlike is_edge_on_surface(), this does NOT short-circuit on the (possibly stale) per-vertex flag – it counts the incident tets' face attributes directly.

◆ face_is_on_surface()

bool wmtk::TetOptimizerMesh::face_is_on_surface ( const size_t  fid) const
overridevirtual

Is a face part of the substructure.

Parameters
fidFace ID

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ get_order_of_vertex()

size_t wmtk::TetOptimizerMesh::get_order_of_vertex ( const size_t  vid) const
overridevirtual

Get the order of a vertex.

The order of a vertex in a TetMesh is as follows: 0: vertex is not on the surface 1: vertex is on the surface 2: vertex is on the surface boundary or a non-manifold edge 3: vertex is at the boundary of a non-manifold edge or a non-manifold vertex

Computing the vertex order is expensive. It is recommended to store the vertex order as a vertex attribute and override this method.

Parameters
vidVertex ID

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ invariants()

bool wmtk::TetOptimizerMesh::invariants ( const std::vector< Tuple > &  t)
overridevirtual

◆ is_open_boundary_edge()

virtual bool wmtk::TetOptimizerMesh::is_open_boundary_edge ( const Tuple e)
inlinevirtual

Whether edge e lies on the boundary of the tracked surface.

Flipping such an edge would change the surface's boundary loops, so prepare_surface_flip refuses it. Defaults to false, which is exact for simwild: its surface is the interface between differently tagged tets, and around an interior edge the tags change an even number of times going around the tet ring, so an interface can never terminate there. It can only end where it meets the bbox – and is_edge_on_bbox() has already rejected those edges by the time this is asked. tetwild overrides it because its surface is the input mesh, which may be non-watertight anywhere.

Reimplemented in wmtk::components::tetwild::TetWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ optimization_quality_stats()

std::tuple< double, double > wmtk::TetOptimizerMesh::optimization_quality_stats ( )
protectedvirtual

Quality metric used by the driver. TetWild uses absolute AMIPS; SimWild overrides this with quality normalized by each cell's tag-dependent target.

Reimplemented in wmtk::components::simwild::SimWildMesh.

◆ quality_rel()

virtual double wmtk::TetOptimizerMesh::quality_rel ( const size_t  tid) const
inlinevirtual

A cell's quality relative to the quality it is required to reach; <= 1 means it meets it.

The only quality that is comparable ACROSS cells. Raw cell_quality is not, once an application gives different regions different targets: the loose region's raw ceiling then hides degradation in the strict one, because a strict cell may get much worse and still sit below a number set somewhere it has nothing to do with. Shared code that compares one cell's quality against another's must go through here.

The cube root is because cell_quality stores AMIPS^3, so that this means the same thing as its 2D twin: AMIPS relative to target, not AMIPS^3 relative to target. TetWild's target is uniform, so this is a monotone function of the raw quality divided by a constant – neither of which can change the outcome of a before/after comparison, so its behaviour is unchanged.

Reimplemented in wmtk::components::simwild::SimWildMesh.

◆ refine_sizing_around_worst()

virtual size_t wmtk::TetOptimizerMesh::refine_sizing_around_worst ( double  max_metric)
protectedpure virtual

◆ region_max_quality_rel()

double wmtk::TetOptimizerMesh::region_max_quality_rel ( const std::vector< size_t > &  vids) const
private

Worst relative quality (quality_rel) over the cells incident to any vertex of vids.

◆ round()

bool wmtk::TetOptimizerMesh::round ( const Tuple v)

Round a vertex position to floating point, if that inverts no incident tet.

Returns
True if successful or already rounded, false otherwise.

◆ round_vertex()

bool wmtk::TetOptimizerMesh::round_vertex ( const size_t  vid)
inlineoverrideprotectedvirtual

Try to replace this vertex's exact position with its rounded one; false if that would invert an incident cell, in which case nothing is changed.

Implements wmtk::RationalPositions.

◆ smooth_after()

bool wmtk::TetOptimizerMesh::smooth_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after smoothing a vertex.

Parameters
tTuple refering to a vertex
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ smooth_before()

bool wmtk::TetOptimizerMesh::smooth_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for smoothing a vertex.

Parameters
tTuple refering to a vertex Tuple
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ smoothing_containment_envelope()

std::shared_ptr< SampleEnvelope > wmtk::TetOptimizerMesh::smoothing_containment_envelope ( const size_t  vid) const
virtual

Envelope the resulting surface triangles are checked against.

The surface envelope is shared by both applications. A derived mesh may additionally select an order-2 feature envelope for the pull energy.

◆ smoothing_energy_envelope()

virtual std::shared_ptr< SampleEnvelope > wmtk::TetOptimizerMesh::smoothing_energy_envelope ( const size_t  vid) const
pure virtual

◆ split_adjust_position()

virtual bool wmtk::TetOptimizerMesh::split_adjust_position ( size_t  ,
const std::vector< Tuple > &   
)
inlineprotectedvirtual

Optional annotation-only adjustment of the midpoint. Ordinary optimization returns true without changing the shared TetWild position.

Reimplemented in wmtk::components::simwild::SimWildMesh.

◆ split_after_cells()

virtual bool wmtk::TetOptimizerMesh::split_after_cells ( size_t  ,
size_t  ,
size_t  ,
const std::vector< Tuple > &   
)
inlineprotectedvirtual

Restore application cell data on the children made by a split.

Reimplemented in wmtk::components::simwild::SimWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ split_after_vertex()

virtual void wmtk::TetOptimizerMesh::split_after_vertex ( size_t  ,
bool   
)
inlineprotectedvirtual

Application metadata not represented by the shared vertex attributes.

Reimplemented in wmtk::components::tetwild::TetWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ split_before_cells()

virtual bool wmtk::TetOptimizerMesh::split_before_cells ( const Tuple ,
const std::vector< Tuple > &   
)
inlineprotectedvirtual

Cache application cell data before a split. TetWild needs none; SimWild caches tags.

Reimplemented in wmtk::components::simwild::SimWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ split_edge_after()

bool wmtk::TetOptimizerMesh::split_edge_after ( const Tuple t)
overridevirtual

This function computes the attributes for the added simplices. User specified modifications and desideratas for after an edge split.

Parameters
theedge Tuple to be split
Returns
true if the modification succeed

check inversion & rounding

update quality

containment: the new surface triangles must stay inside the envelope

update vertex attribute

update face attribute

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ split_edge_before()

bool wmtk::TetOptimizerMesh::split_edge_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for an edge split before changing the connectivity.

Parameters
theedge Tuple to be split
Returns
true if the preparation succeed

save face track info

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ surface_envelope_for_face()

virtual std::shared_ptr< SampleEnvelope > wmtk::TetOptimizerMesh::surface_envelope_for_face ( const std::array< size_t, 3 > &  vids) const
inlinevirtual

Envelope the tracked-surface triangle vids must stay inside.

Null means this triangle carries no containment requirement, and every containment check on it is skipped. Both applications that track a single surface keep one envelope for it, so the default answers with that; an application tracking more than one surface (see SurfaceTagAttributes::m_surface_class) overrides this to answer per class – the offset boundary, for instance, is free to move and is checked against nothing.

Keyed on the vertex ids rather than the fid because every caller is a topological operation asking about the triangles it is ABOUT to create or has just created, where only the vids are known for certain.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ surface_triangle_is_outside()

bool wmtk::TetOptimizerMesh::surface_triangle_is_outside ( const size_t  a,
const size_t  b,
const size_t  c 
) const
inline

Whether the tracked-surface triangle (a,b,c) is outside its containment envelope. False when it has none. Every surface containment check in the operations goes through here.

◆ swap_after_cells()

virtual bool wmtk::TetOptimizerMesh::swap_after_cells ( const std::vector< size_t > &  ,
bool   
)
inlineprotectedvirtual

Propagate application data to the cells made by a successful topological swap.

Reimplemented in wmtk::components::simwild::SimWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ swap_before_interior()

virtual bool wmtk::TetOptimizerMesh::swap_before_interior ( const std::vector< size_t > &  )
inlineprotectedvirtual

Application data attached to the old cells. TetWild has none; SimWild caches tags.

Reimplemented in wmtk::components::simwild::SimWildMesh, and wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ swap_edge_44_accept_case()

bool wmtk::TetOptimizerMesh::swap_edge_44_accept_case ( const std::array< size_t, 2 > &  new_edge)
overridevirtual

Filter which of the 4-4 orientations may be chosen.

Called for every candidate 4-4 case (identified by its new edge) BEFORE the energy-based selection; a candidate whose new edge is rejected here is not considered. The default accepts everything, so interior edges keep the pure min-energy behavior. A derived mesh can override this to force a specific retetrahedralization (e.g. tetwild forces the case that realizes a surface diagonal flip).

Parameters
new_edgeThe two vertices of the candidate's new edge. The ordering is implementation-defined (currently new_edge[0] is the case-selector vertex).

Reimplemented from wmtk::TetMesh.

◆ swap_edge_44_after()

bool wmtk::TetOptimizerMesh::swap_edge_44_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after a 4-4 edge swap.

Parameters
tedge Tuple that's swaped
Returns
true if the modification succeed

Reimplemented from wmtk::TetMesh.

◆ swap_edge_44_before()

bool wmtk::TetOptimizerMesh::swap_edge_44_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for an 4-4 edge swap before changing the connectivity.

Parameters
tedge Tuple to be swaped
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

◆ swap_edge_44_energy()

double wmtk::TetOptimizerMesh::swap_edge_44_energy ( const std::vector< std::array< size_t, 4 > > &  tets,
const int  op_case 
)
overridevirtual

User specified energy to decide which of the 4 possible orientations should be chosen.

Accepts the last shown orientation if not overridden.

Parameters
tetsNew tets after performing a 4-4 swap.
op_caseThe operation case, where 0 are the tets before swap.
Returns
energy The swap giving the tets with the lowest energy are chosen.

Reimplemented from wmtk::TetMesh.

◆ swap_edge_56_accept_case()

bool wmtk::TetOptimizerMesh::swap_edge_56_accept_case ( const std::array< size_t, 3 > &  new_face)
overridevirtual

Filter which of the 5-6 orientations may be chosen.

Called for every candidate 5-6 case (identified by its new fan face) BEFORE the energy-based selection; a candidate whose new face is rejected here is not considered. The default accepts everything, so interior edges keep the pure min-energy behavior. new_face[0] is the fan apex. A derived mesh can override this to force a specific retetrahedralization (e.g. tetwild forces the fan that realizes a surface diagonal flip).

Parameters
new_faceThe candidate's new fan face; new_face[0] is the fan apex.
Returns
true if this candidate case is allowed.

Reimplemented from wmtk::TetMesh.

◆ swap_edge_56_after()

bool wmtk::TetOptimizerMesh::swap_edge_56_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after a 5-6 edge swap.

Parameters
tedge Tuple that's swaped
Returns
true if the modification succeed

There is no need to check for inversion or energy here. The operation would have been rejected already due to swap_edge_56_energy().

Reimplemented from wmtk::TetMesh.

◆ swap_edge_56_before()

bool wmtk::TetOptimizerMesh::swap_edge_56_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for a 5-6 edge swap before changing the connectivity.

Parameters
tedge Tuple to be swaped
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

◆ swap_edge_56_energy()

double wmtk::TetOptimizerMesh::swap_edge_56_energy ( const std::vector< std::array< size_t, 4 > > &  tets,
const int  op_case 
)
overridevirtual

User specified energy to decide which of the 5 possible orientations should be chosen.

Accepts the last shown orientation if not overridden.

Parameters
tetsNew tets after performing a 5-6 swap.
op_caseThe operation case, where 0 are the tets before swap.
Returns
energy The swap giving the tets with the lowest energy are chosen.

Reimplemented from wmtk::TetMesh.

◆ swap_edge_after()

bool wmtk::TetOptimizerMesh::swap_edge_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after a 3-2 edge swap.

Parameters
tedge Tuple that's swaped
Returns
true if the modification succeed

Setting the m_is_surface_fs flag to true is not necessary. This is already true in cache.sf_face_attr.

Reimplemented from wmtk::TetMesh.

◆ swap_edge_before()

bool wmtk::TetOptimizerMesh::swap_edge_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for an 3-2 edge swap before changing the conenctivity.

Parameters
tedge Tuple to be swaped
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

◆ swap_face_after()

bool wmtk::TetOptimizerMesh::swap_face_after ( const Tuple t)
overridevirtual

User specified modifications and desideratas for after a 2-3 face swap.

Parameters
tedge Tuple that's swaped
Returns
true if the modification succeed

Reimplemented from wmtk::TetMesh.

◆ swap_face_before()

bool wmtk::TetOptimizerMesh::swap_face_before ( const Tuple t)
overridevirtual

User specified preparations and desideratas for an 2-3 face swap befroe changing the geometry.

Parameters
tedge Tuple to be swaped
Returns
true if the preparation succeed

Reimplemented from wmtk::TetMesh.

◆ vertex_is_on_surface()

bool wmtk::TetOptimizerMesh::vertex_is_on_surface ( const size_t  vid) const
overridevirtual

Is a vertex part of the substructure.

Parameters
vidVertex ID

Reimplemented from wmtk::TetMesh.

Reimplemented in wmtk::components::topological_offset::TopoOffsetTetMesh.

◆ vertex_is_rounded()

bool wmtk::TetOptimizerMesh::vertex_is_rounded ( const size_t  vid) const
inlineoverrideprotectedvirtual

Whether this vertex's double position is currently trusted.

Implements wmtk::RationalPositions.

Member Data Documentation

◆ m_collapse_limit_length

bool wmtk::TetOptimizerMesh::m_collapse_limit_length = true

Whether the current collapse pass applies the target-length limit; read by collapse_edge_before, which is where that limit is enforced.

◆ m_face_attr_group

AttributeContainerGroup wmtk::TetOptimizerMesh::m_face_attr_group

What p_face_attrs points at, so a derived class can register more.

The counterpart of m_vertex_attr_group for faces. An application whose faces carry data the shared operations know nothing about – topological_offset labels each face by which part of the construction produced it – registers a second collection here, and it is resized, protected and rolled back with the shared one.

Note what this does NOT do: the shared operations propagate face data by copying SurfaceTagAttributes values around (the split and collapse caches, the swap tracker), and they only ever see their own collection. Anything registered here survives the mesh changing shape, but its values are the registering application's to maintain.

◆ m_force_split_edges

std::set<simplex::Edge> wmtk::TetOptimizerMesh::m_force_split_edges

The longest edge of each current worst tet. split_all_edges force-splits exactly these edges (bypassing the length gate). Populated serially by refine_sizing_around_worst; read-only during the parallel split pass, then cleared once consumed.

◆ m_params

OptimizerParameters& wmtk::TetOptimizerMesh::m_params

Only the fields shared by all three applications; each derived class keeps a typed reference to its own Parameters for the rest.

◆ m_s_amips

double wmtk::TetOptimizerMesh::m_s_amips = 1.

Scale factors putting AMIPS (dimensionless) and the envelope energy (a squared distance) on a comparable footing.

◆ m_vertex_attr_group

AttributeContainerGroup wmtk::TetOptimizerMesh::m_vertex_attr_group

What p_vertex_attrs points at, so a derived class can register more.

VertexAttributes holds only what both 3D applications need. tetwild adds a per-vertex open-boundary flag through here; simwild never sets one, so it does not carry the field.

◆ MAX_ENERGY

constexpr double wmtk::TetOptimizerMesh::MAX_ENERGY = 1e50
staticconstexpr

The sentinel get_quality returns for an element AMIPS cannot score.

Not an energy: a positively oriented tet whose volume is too small for AMIPS, or one that produces inf/nan, gets this instead. The cell quality holds AMIPS^3, so it surfaces in the logs as its cube root, cbrt(1e50) = 4.6e16. 1e50 rather than double::max because every downstream ratio must stay finite – avg_energy sums qualities and would go inf.


The documentation for this class was generated from the following files: