10#include <wmtk/TetMesh.h>
11#include <wmtk/TetOptimizerMesh.h>
12#include <wmtk/envelope/Envelope.hpp>
13#include <wmtk/optimization/solver.hpp>
14#include <wmtk/simplex/Simplex.hpp>
15#include <wmtk/threading/enumerable_thread_specific.hpp>
16#include "OffsetPotential.hpp"
17#include "Parameters.h"
18#include "SimplicialComplexBVH.hpp"
21#include <wmtk/utils/DisableWarnings.hpp>
22#include <wmtk/utils/EnableWarnings.hpp>
25using CellTag = std::set<int64_t>;
28namespace wmtk::components::topological_offset {
30const int64_t TEMP_OFFSET_TET_TAG = -1;
31const CellTag TEMP_OFFSET_TET_TAG_SET{TEMP_OFFSET_TET_TAG};
49 size_t component_id = 0;
54 bool m_is_on_offset =
false;
110 double m_quality = 0;
171 PhaseBSub m_phase_b_sub = PhaseBSub::Offset;
254 enum class EdgeSplitMode {
261 int m_vtu_counter = 0;
262 std::array<size_t, 4> m_init_counts = {{0, 0, 0, 0}};
264 SimplicialComplexBVH m_input_complex_bvh;
313 mutable std::mutex m_isect_mutex;
315 EdgeSplitMode m_edge_split_mode = EdgeSplitMode::Midpoint;
318 std::map<std::string, int64_t> m_tag_name_to_id;
319 std::map<int64_t, std::string> m_tag_id_to_name;
320 CellTag m_offset_output_tag_ids;
323 bool m_singlebody =
false;
324 int64_t m_single_tag;
328 std::vector<Vector3d> m_V_envelope;
329 std::vector<Vector3i> m_F_envelope;
332 double m_envelope_eps = -1;
362 return FaceSnapshot{m_face_attribute[fid], m_face_extra[fid]};
364 void restore_face(
const size_t fid,
const FaceSnapshot& s)
366 m_face_attribute[fid] = s.tags;
367 m_face_extra[fid] = s.extra;
381 m_vertex_attribute[vid].m_posf = p;
382 m_vertex_attribute[vid].m_pos = to_rational(p);
383 m_vertex_attribute[vid].m_is_rounded =
true;
396 const int l = m_tet_attribute[tid].label;
397 return l == 1 || l == 2;
403 return m_face_attribute[fid].m_is_surface_fs &&
409 return m_face_attribute[fid].m_is_surface_fs &&
414 std::atomic<int> cnt_split = 0, cnt_collapse = 0;
420 NUM_THREADS = _num_threads;
425 p_edge_attrs = &m_edge_attribute;
426 p_tet_attrs = &m_tet_attribute;
428 m_collapse_check_link_condition =
false;
429 m_collapse_check_manifold =
false;
437 optimization::deactivate_opt_logger();
440 ~TopoOffsetTetMesh()
override =
default;
444 double cell_quality(
const size_t tid)
const override {
return m_tet_attribute[tid].m_quality; }
445 void set_cell_quality(
const size_t tid,
const double q)
override
452 const double before = m_tet_attribute[tid].m_quality;
468 m_tet_attribute[tid].m_quality = q;
475 return std::isfinite(q) ? std::cbrt(q) : std::numeric_limits<double>::infinity();
487 void log_quality_spike(
size_t tid,
double before,
double after,
const char* kind)
const;
497 mutable std::atomic<int> m_spike_dumps{0};
498 mutable std::atomic<int> m_spike_genesis_dumps{0};
499 mutable std::atomic<int> m_spike_count{0};
500 mutable std::atomic<int> m_spike_genesis{0};
501 int m_spike_dump_budget = 24;
514 return m_vertex_extra[vid].m_is_on_region || !m_vertex_attribute[vid].on_bbox_faces.empty();
522 for (
const int64_t t : tags) {
524 if (it !=
m_tag_bit.end()) bits |= (uint64_t(1) << it->second);
546 uint64_t
face_mask(
const std::array<size_t, 3>& vids)
const
564 const std::array<size_t, 3>& vids)
const override
570 if (
const uint64_t mask =
face_mask(vids)) {
576 bool all_offset =
true;
577 for (
const size_t v : vids) {
578 all_offset = all_offset && m_vertex_extra[v].m_is_on_offset;
588 bool check_surface_topology()
const override {
return m_offset_params.perform_sanity_checks; }
616 std::shared_ptr<SampleEnvelope> best;
617 double worst_d2 = -1.;
620 if (it ==
m_tag_bit.end() || !(mask & (uint64_t(1) << it->second)))
continue;
623 if ((mask & (mask - 1)) == 0)
break;
624 worst_d2 = env->squared_distance(m_vertex_attribute[vid].m_posf);
627 const double d2 = env->squared_distance(m_vertex_attribute[vid].m_posf);
712 return m_phase == OptPhase::A ? wmtk::TetOptimizerMesh::optimization_stop_metric() : 1.;
785 return m_vertex_attribute[vid].on_bbox_faces.empty();
822 template <
typename Visit>
828 const auto vs = get_face_vids(f);
829 const Vector3d p0 = m_vertex_attribute[vs[0]].m_posf;
830 const Vector3d p1 = m_vertex_attribute[vs[1]].m_posf;
831 const Vector3d p2 = m_vertex_attribute[vs[2]].m_posf;
834 for (
int i = 1; i < n; ++i) {
835 for (
int j = 1; j < n - i; ++j) {
836 const int l = n - i - j;
838 visit(Vector3d((
double(i) * p0 +
double(j) * p1 +
double(l) * p2) /
double(n)));
879 double max_reachable = 0., avg_reachable = 0.;
880 double max_pinned = 0.;
881 size_t n_reachable = 0, n_pinned = 0;
889 size_t worst_outside_vid =
static_cast<size_t>(-1);
890 double worst_outside_dist = 0.;
916 double max_reachable = 0., avg_reachable = 0.;
917 double max_pinned = 0.;
918 size_t n_reachable = 0, n_pinned = 0;
948 bool swap_before_surface(
949 const std::vector<size_t>& tids,
954 bool swap_after_cells(
const std::vector<size_t>& tids,
bool is_surface_flip)
override;
966 bool collapse_after_connectivity(
969 const std::vector<std::array<size_t, 2>>& boundary_edges)
override;
970 bool collapse_is_order_2_edge(
const std::array<size_t, 2>& e)
override
972 return is_order_2_edge(e);
974 void collapse_after_vertex(
size_t v1,
size_t v2)
override;
989 mutable OffsetCollapseRefusals m_offset_collapse_refusals;
1001 bool split_before_cells(
const Tuple& edge,
const std::vector<Tuple>& parents)
override;
1002 bool split_after_cells(
size_t v1,
size_t v2,
size_t v_new,
const std::vector<Tuple>& children)
1018 bool is_edge_on_region =
false;
1019 bool is_edge_on_offset =
false;
1020 std::map<simplex::Edge, TetAttributes> tets;
1053 const MatrixSi& T_tags,
1054 const MatrixXd& V_env,
1055 const MatrixXi F_env,
1056 const std::vector<std::string>& tag_names);
1058 void init_surfaces_and_boundaries();
1063 bool is_edge_on_offset(
const Tuple& loc);
1109 std::vector<int> m_phi_P;
1117 std::vector<std::array<size_t, 3>> get_faces_by_condition(
1125 bool marching_split_edge_before(
const Tuple& t);
1131 bool invariants(
const std::vector<Tuple>& tets)
override;
1203 for (std::atomic<int>* c :
1216 mutable SmoothTrace m_smooth_trace;
1218 void log_smooth_trace()
const;
1232 std::unique_ptr<polysolve::nonlinear::Solver>>
1243 enum class VClass { Bbox = 0, Offset = 1, Input = 2, Interior = 3, Count = 4 };
1245 VClass vertex_class(
const size_t vid)
const
1247 if (!m_vertex_attribute[vid].on_bbox_faces.empty())
return VClass::Bbox;
1248 if (m_vertex_extra[vid].m_is_on_offset)
return VClass::Offset;
1249 if (m_vertex_extra[vid].m_is_on_region)
return VClass::Input;
1250 return VClass::Interior;
1253 static const char* vclass_name(
VClass c)
1256 case VClass::Bbox:
return "bbox";
1257 case VClass::Offset:
return "offset";
1258 case VClass::Input:
return "input";
1259 default:
return "interior";
1276 std::atomic<int> attempted{0};
1277 std::atomic<int> refused_before{0};
1278 std::atomic<int> accepted{0};
1279 std::atomic<double> sum_disp{0.};
1280 std::atomic<double> max_disp{0.};
1285 for (
double cur = sum_disp.load(); !sum_disp.compare_exchange_weak(cur, cur + d);) {
1287 for (
double cur = max_disp.load();
1288 d > cur && !max_disp.compare_exchange_weak(cur, d);) {
1292 mutable std::array<
MoveStats, size_t(VClass::Count)> m_move_stats;
1314 void note(
bool zero_tracked,
double dev_before,
double dev_after)
1318 const double d = dev_after - dev_before;
1328 mutable WallMoveStats m_wall_moves;
1374 void diag_offset_bands(
const char* tag)
const;
1395 void log_worst_dist_vertex()
const;
1432 std::atomic<int> iter_cnt_recollapsed{0};
1433 std::atomic<int> iter_cnt_recollapsed_same_pass{0};
1434 std::atomic<int> iter_cnt_split{0};
1435 std::atomic<int> iter_cnt_collapse{0};
1436 std::atomic<int> iter_cnt_swap{0};
1437 std::atomic<int> iter_cnt_collapse_offset_removed{0};
1440 std::atomic<int> iter_cnt_swap_offset_reject{0};
1443 std::atomic<int> iter_cnt_split_offset_endpoints{0};
1444 std::atomic<int> iter_cnt_split_offset_base_reject{0};
1445 std::atomic<int> iter_cnt_split_offset_tried{0};
1446 std::atomic<int> iter_cnt_split_offset{0};
1447 std::atomic<int> iter_cnt_split_offset_reject{0};
1463 static double mean_ratio_metric(
const Vector3d& p0,
const Vector3d& p1,
const Vector3d& p2);
1514 void write_input_complex(
const std::string& path);
1515 void write_vtu(
const std::string& path);
1517 void write_msh_groups(
const std::string& file);
1535 bool is_edge_on_region =
false;
1536 bool is_edge_on_offset =
false;
1537 bool is_edge_open_boundary =
false;
1539 std::vector<std::pair<FaceAttributes, std::array<size_t, 3>>> changed_faces;
1543 std::map<size_t, EdgeAttributes> internal_e;
1544 std::map<simplex::Edge, EdgeAttributes> external_e;
1545 std::map<simplex::Edge, EdgeAttributes> link_e;
1548 std::map<size_t, FaceSnapshot> split_f;
1549 std::map<simplex::Edge, FaceSnapshot> internal_f;
1550 std::map<std::pair<simplex::Edge, size_t>,
FaceSnapshot>
1554 std::map<simplex::Edge, TetAttributes> tets;
1565 std::map<simplex::Edge, EdgeAttributes> existing_e;
1568 std::map<simplex::Face, FaceSnapshot> existing_f;
1572 std::map<size_t, TetAttributes> tets;
1578 std::array<size_t, 4> v_ids;
1581 std::map<simplex::Edge, EdgeAttributes> existing_e;
1584 std::map<simplex::Face, FaceSnapshot> existing_f;
1595 bool is_order_2_edge(
const Tuple& e)
const;
1596 bool is_order_2_edge(
const std::array<size_t, 2>& e)
const;
1617 return tag1.empty();
1623 for (
const int64_t& i : tag1) {
1624 if (tag2.find(i) != tag2.end()) {
1640 double len1 = (m_vertex_attribute[e1.vertices()[0]].m_posf -
1641 m_vertex_attribute[e1.vertices()[1]].m_posf)
1643 double len2 = (m_vertex_attribute[e2.vertices()[0]].m_posf -
1644 m_vertex_attribute[e2.vertices()[1]].m_posf)
1658 size_t get_partition_id(
const Tuple& loc)
const
1660 return m_vertex_attribute[loc.vid(*
this)].partition_id;
1668 std::vector<Tuple> adj_tets;
1669 auto tet_1 = t.switch_tetrahedron(*
this);
1671 adj_tets.push_back(tet_1.value());
1673 auto tet_2 = t.switch_face(*this).switch_tetrahedron(*
this);
1675 adj_tets.push_back(tet_2.value());
1677 auto tet_3 = t.switch_edge(*this).switch_face(*this).switch_tetrahedron(*
this);
1679 adj_tets.push_back(tet_3.value());
1682 t.switch_vertex(*this).switch_edge(*this).switch_face(*this).switch_tetrahedron(*
this);
1684 adj_tets.push_back(tet_4.value());
1695 std::vector<size_t> ret_v_ids;
1696 for (
const size_t& other_v_id : onering_v_ids) {
1698 if (m_edge_attribute[e_id].label != 0) {
1699 ret_v_ids.push_back(other_v_id);
1711 for (
const Tuple& v : verts) {
1712 size_t v_id = v.vid(*
this);
1713 m_vertex_extra[v_id].component_id = 0;
Whether a codimension-1 simplex is tracked surface, and which bbox side it lies on.
Definition SurfaceTagAttributes.h:15
a Tuple refers to a global vid and a global tet id, and a local edge id and local face id
Definition TetMesh.h:50
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.
Definition TetMesh.cpp:800
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).
Definition TetMesh.cpp:342
std::vector< Tuple > get_vertices() const
Definition TetMesh.cpp:311
What tetwild and simwild's 3D mesh share.
Definition TetOptimizerMesh.h:45
AttributeContainerGroup m_vertex_attr_group
What p_vertex_attrs points at, so a derived class can register more.
Definition TetOptimizerMesh.h:92
AttributeContainerGroup m_face_attr_group
What p_face_attrs points at, so a derived class can register more.
Definition TetOptimizerMesh.h:107
Definition TopoOffsetTetMesh.h:84
Definition TopoOffsetTetMesh.h:106
The offset's tet mesh, on the shared 3D optimizer.
Definition TopoOffsetTetMesh.h:125
std::vector< std::array< int, 3 > > churn_counts
Definition TopoOffsetTetMesh.h:1419
std::atomic< int > m_phase_b_constrained
Definition TopoOffsetTetMesh.h:1225
std::atomic< int > iter_cnt_split_born
Definition TopoOffsetTetMesh.h:1431
std::vector< Tuple > get_face_adjacent_tets(const Tuple &t) const
get tets (as Tuples) that are face-adjacent to the given tet (as Tuple)
Definition TopoOffsetTetMesh.h:1666
bool split_edge_after(const Tuple &t) override
This function computes the attributes for the added simplices. User specified modifications and desid...
Definition EdgeSplittingTet.cpp:138
size_t refine_sizing_around_worst(double) override
Phase A's stall-driven sizing refinement – TetWild's, on element quality.
Definition TopoOffsetTetMesh.cpp:1927
OptPhase m_phase
Which phase is running. Read by every hook that differs between them; see OptPhase.
Definition TopoOffsetTetMesh.h:155
std::atomic< int > iter_cnt_collapse_offset_reject
Operations refused because they would have left an offset face over tolerance.
Definition TopoOffsetTetMesh.h:1439
MatrixXd m_phi_V
Definition TopoOffsetTetMesh.h:1106
size_t m_worst_dist_vid
Definition TopoOffsetTetMesh.h:1394
double optimization_stop_metric() const override
Definition TopoOffsetTetMesh.h:710
std::tuple< double, double > optimization_quality_stats() override
(max, avg) Phi residual over the reachable offset surface, in units of its tolerance; the engine's st...
Definition TopoOffsetTetMesh.cpp:1876
wmtk::threading::enumerable_thread_specific< std::unique_ptr< polysolve::nonlinear::Solver > > m_phase_b_solver
Definition TopoOffsetTetMesh.h:1233
bool is_offset_face(const Tuple &f) const
true if face f has exactly one incident tet labelled 2 (offset), i.e. it lies on the boundary between...
Definition Smooth.cpp:357
FaceSamples offset_face_samples(const Tuple &f) const
The Phi residual at offset_residual_samples interior points of offset face f.
Definition TopoOffsetTetMesh.cpp:2322
bool cell_is_offset_band(const size_t tid) const
Whether tet tid is part of the offset BAND (as opposed to the input complex it wraps).
Definition TopoOffsetTetMesh.h:1377
void report_outside_support(const char *when, const DistanceSplit &s) const
Definition TopoOffsetTetMesh.cpp:2406
void sort_edges_by_length(std::vector< simplex::Edge > &edges)
sort edge simplices in place by decreasing edge length
Definition TopoOffsetTetMesh.h:1634
wmtk::threading::enumerable_thread_specific< double > m_collapse_offset_rel_before
Definition TopoOffsetTetMesh.h:1030
VClass
Which of four DISJOINT classes a vertex is accounted to when measuring movement.
Definition TopoOffsetTetMesh.h:1243
wmtk::threading::enumerable_thread_specific< int > m_swap_label
Definition TopoOffsetTetMesh.h:1039
std::shared_ptr< SampleEnvelope > smoothing_energy_envelope(const size_t vid) const override
The offset surface is the one tracked surface with NO envelope, in either role.
Definition TopoOffsetTetMesh.h:604
void log_vertex_movement(const char *when) const
Per-class smoothing movement, plus the direct bounding-box invariant check.
Definition TopoOffsetTetMesh.cpp:2516
uint64_t face_mask(const std::array< size_t, 3 > &vids) const
A face lies on a boundary only if all of it does: the AND of its corners' masks.
Definition TopoOffsetTetMesh.h:546
void for_each_offset_face_sample(const Tuple &f, Visit &&visit) const
The interior lattice a face is sampled on, handed to visit one point at a time.
Definition TopoOffsetTetMesh.h:823
void log_quality_spike(size_t tid, double before, double after, const char *kind) const
Report one tet crossing into absurd quality: its geometry, and why it is degenerate.
Definition TopoOffsetTetMesh.cpp:2658
size_t get_order_of_vertex(const size_t vid) const override
Get the order of a vertex.
Definition TopoOffsetTetMesh.cpp:1058
void reset_connected_components()
reset connected component assignments.
Definition TopoOffsetTetMesh.h:1708
size_t flood_fill()
label connected simplicial complex components (simplices labelled 1 or 2)
Definition TopoOffsetTetMesh.cpp:985
void init_from_image(const MatrixXd &V, const MatrixXi &T, const MatrixSi &T_tags, const MatrixXd &V_env, const MatrixXi F_env, const std::vector< std::string > &tag_names)
initialize TetMesh from vertex, tet, and tag data
Definition TopoOffsetTetMesh.cpp:36
bool split_after_cells(size_t v1, size_t v2, size_t v_new, const std::vector< Tuple > &children) override
Restore application cell data on the children made by a split.
Definition EdgeSplittingTet.cpp:531
std::vector< bool > band_vertex_mask() const
Definition TopoOffsetTetMesh.cpp:2336
void init_offset_sizing_field()
Seed the sizing field from the offset surface's current edge lengths, once, before the first pass....
Definition TopoOffsetTetMesh.cpp:2092
std::shared_ptr< SampleEnvelope > envelope_for_mask(uint64_t mask) const
The envelope a simplex with this boundary mask is contained in, or null.
Definition TopoOffsetTetMesh.cpp:856
void log_worst_tet(const char *when) const
Diagnostic: dump the single worst-quality tet and everything that could be pinning it,...
Definition TopoOffsetTetMesh.cpp:2726
double offset_gradient_tolerance() const
The convergence tolerance: the bound on |grad (Phi - c)^2| at a band vertex.
Definition TopoOffsetTetMesh.h:738
bool cell_in_region(const size_t tid) const
Whether tet tid belongs to the closed offset region, read from its TAGS.
Definition TopoOffsetTetMesh.h:394
bool collapse_edge_before(const Tuple &t) override
Collapse policy that is the offset's own.
Definition Collapse.cpp:12
void marching_tets()
execute simplistic marching tets. All edges with one vertex labelled 0 and the other 1/2 are split,...
Definition TopoOffsetTetMesh.cpp:3403
bool smooth_before(const Tuple &t) override
Definition Smooth.cpp:14
bool split_edge_before(const Tuple &t) override
Definition EdgeSplittingTet.cpp:13
std::shared_ptr< OffsetPotential3D > m_offset_potential
The smooth offset potential Phi of the input complex, as loaded.
Definition TopoOffsetTetMesh.h:274
void init_offset_potential()
Build the smooth offset potential from the extraction init_input_complex_bvh() kept.
Definition TopoOffsetTetMesh.cpp:897
void set_offset_tet_tags()
update 'tags' data for tets in the offset region (tets labelled 2) based on the given offset tag valu...
Definition TopoOffsetTetMesh.cpp:3475
bool split_tet_after(const Tuple &t) override
Compute the attributes for the added simplices.
Definition EdgeSplittingTet.cpp:449
bool face_is_on_surface(const size_t fid) const override
Is a face part of the substructure.
Definition TopoOffsetTetMesh.cpp:1053
bool ambient_assert()
check that the ambient tag does not overlap with any other tags
Definition TopoOffsetTetMesh.cpp:350
std::shared_ptr< SampleEnvelope > m_input_complex_envelope
The exact-kind envelope of the input complex, built only for offset_field "euclidean"....
Definition TopoOffsetTetMesh.h:285
void compute_vertex_partition()
assign each vertex a partition id (by spatial Morton order) for the parallel ExecutePass policies (kP...
Definition TopoOffsetTetMesh.cpp:1077
double amips_rel_at_face(const Tuple &f) const
... and the worst of the (up to two) cells a face separates.
Definition TopoOffsetTetMesh.cpp:2441
double max_band_vertex_distance() const
Definition TopoOffsetTetMesh.cpp:2262
double offset_residual_tolerance() const
Definition TopoOffsetTetMesh.h:720
void mark_input_complex_vertices()
Definition TopoOffsetTetMesh.cpp:587
std::atomic< int > iter_cnt_split_offset_before
Splits of an OFFSET-surface edge: reached split_edge_after, accepted, refused there.
Definition TopoOffsetTetMesh.h:1442
bool cell_is_input_complex(const size_t tid) const
Whether tet tid is part of the INPUT complex the band wraps.
Definition TopoOffsetTetMesh.h:1380
std::shared_ptr< SampleEnvelope > smoothing_containment_envelope(const size_t vid) const override
... and it is not CONTAINED by one either.
Definition TopoOffsetTetMesh.h:654
bool marching_split_edge_after(const Tuple &t)
Definition EdgeSplittingTet.cpp:154
bool face_is_offset(const size_t fid) const
Whether face fid is on the offset boundary (as opposed to the input complex).
Definition TopoOffsetTetMesh.h:401
bool split_face_before(const Tuple &t) override
User specified preparations and desideratas for a face split before changing the connectivity.
Definition EdgeSplittingTet.cpp:248
Parameters & m_offset_params
Definition TopoOffsetTetMesh.h:336
bool offset_is_manifold()
verify that the closed offset region (simplices labelled 1 or 2) form a manifold region....
Definition TopoOffsetTetMesh.cpp:3510
uint64_t vertex_boundary_mask(const size_t vid) const
The tag boundaries this vertex lies on – the raw mask, gated on the vertex still being region geometr...
Definition TopoOffsetTetMesh.h:540
void write_optimization_debug_output(const std::string &path) override
Definition TopoOffsetTetMesh.h:674
bool smooth_offset_vertex_backtracking(const Tuple &t)
Phase B's placement of an offset-surface vertex: the offset energy alone, then backtrack into the one...
Definition Smooth.cpp:136
void init_vertex_order()
Compute the vertex order for every vertex.
Definition TopoOffsetTetMesh.cpp:1063
static double mean_ratio_metric(const Vector3d &p0, const Vector3d &p1, const Vector3d &p2)
unsigned mean ratio metric of a triangle: 2*sqrt(3)*area / (sum of squared edge lengths)....
Definition TopoOffsetTetMesh.cpp:1175
void execute_offset(const std::filesystem::path &output_file)
main function from which all others are called
Definition TopoOffsetTetMesh.cpp:1113
bool smooth_interior_vertex_phase_b(const Tuple &t)
Phase B's placement of a background vertex: Newton on the one-ring AMIPS energy, to this vertex's own...
Definition Smooth.cpp:297
bool is_simplicially_embedded() const
check if the input complex (simplices labelled 1) are simplicially embedded w.r.t....
Definition TopoOffsetTetMesh.cpp:3264
bool any_tag_present(const CellTag &tag1, const CellTag &tag2)
determine if any tag from tag1 is also present in tag2.
Definition TopoOffsetTetMesh.h:1614
static double spike_amips(const double q)
Definition TopoOffsetTetMesh.h:473
bool is_edge_on_region(const Tuple &loc)
Definition TopoOffsetTetMesh.cpp:295
bool band_vertex_is_reachable(const size_t vid) const
Definition TopoOffsetTetMesh.h:783
bool m_spike_track
Diagnostic: whether set_cell_quality reports tets crossing into absurd quality.
Definition TopoOffsetTetMesh.h:490
std::shared_ptr< SampleEnvelope > m_offset_envelope
The tube the offset surface may not leave during Phase A. Null in Phase B.
Definition TopoOffsetTetMesh.h:182
double wall_offplane_deviation(const size_t vid) const
Definition TopoOffsetTetMesh.cpp:2504
void set_vertex_position(const size_t vid, const Vector3d &p)
Place a vertex, keeping its exact and rounded coordinates in step.
Definition TopoOffsetTetMesh.h:379
std::vector< size_t > connected_components_helper(const size_t &v_id)
get all one-ring vertices through input simplices (labelled 1)
Definition TopoOffsetTetMesh.h:1692
std::map< int64_t, std::shared_ptr< SampleEnvelope > > m_tag_envelopes
One containment envelope per input tag, ambient included. Both phases.
Definition TopoOffsetTetMesh.h:304
bool collapse_before_vertex(size_t v1, size_t v2, double edge_length) override
Definition Collapse.cpp:31
uint64_t tag_bits(const CellTag &tags) const
Definition TopoOffsetTetMesh.h:519
static constexpr int OFFSET_SURFACE_CLASS
SurfaceTagAttributes::m_surface_class for the offset boundary.
Definition TopoOffsetTetMesh.h:133
void simplicial_embedding()
make mesh a simplicial embedding of the input complex (simplices labelled 1)
Definition TopoOffsetTetMesh.cpp:3309
void warn_if_offset_reaches_domain_boundary() const
Warn if conservative growth ran into the bounding box.
Definition TopoOffsetTetMesh.cpp:2471
double band_vertex_residual(const size_t vid) const
Definition TopoOffsetTetMesh.cpp:2315
void init_input_complex_bvh()
Build the input complex's BVH and keep the extraction the potential needs.
Definition TopoOffsetTetMesh.cpp:626
std::shared_ptr< SampleEnvelope > surface_envelope_for_face(const std::array< size_t, 3 > &vids) const override
Envelope the tracked-surface triangle vids must stay inside.
Definition TopoOffsetTetMesh.h:563
bool allow_surface_swap() const override
Definition TopoOffsetTetMesh.h:587
bool is_open_boundary_edge(const Tuple &e) override
Definition TopoOffsetTetMesh.h:1011
bool swap_before_interior(const std::vector< size_t > &tids) override
Which tag the tets a swap creates should carry.
Definition Swap.cpp:52
bool face_is_region(const size_t fid) const
Whether face fid carries input-complex geometry.
Definition TopoOffsetTetMesh.h:407
double m_spike_record
Largest AMIPS seen so far; a new maximum is logged, which bounds the output.
Definition TopoOffsetTetMesh.h:496
void label_input_complex()
label input simplicial complex simplices, as defined in m_offset_params.offset_selection
Definition TopoOffsetTetMesh.cpp:369
std::pair< double, double > compute_distance_deviation() const
How far the offset surface is from where it should be: {max, avg} over its vertices.
Definition TopoOffsetTetMesh.cpp:2286
void split_after_vertex(size_t v_new, bool is_edge_open_boundary) override
Application metadata not represented by the shared vertex attributes.
Definition EdgeSplittingTet.cpp:592
void rebuild_offset_envelope()
Definition TopoOffsetTetMesh.cpp:1247
std::map< uint64_t, std::shared_ptr< SampleEnvelope > > m_isect_cache
Definition TopoOffsetTetMesh.h:312
std::vector< std::array< int, 3 > > op_counts
Definition TopoOffsetTetMesh.h:1424
bool m_converged
Whether the optimization met both convergence criteria before the iteration cap.
Definition TopoOffsetTetMesh.h:1426
void optimize_offset_alternating()
Definition TopoOffsetTetMesh.cpp:1666
GradientSplit gradient_split(bool include_face_samples=true) const
Definition TopoOffsetTetMesh.cpp:1288
bool swap_capture_tag(const std::vector< size_t > &tids)
Definition Swap.cpp:18
bool tet_is_simp_emb(const Tuple &t) const
check if a tet satisfies simpicial embedding criteria w.r.t. input complex (simplices labelled 1)
Definition TopoOffsetTetMesh.cpp:3281
double m_spike_threshold
AMIPS above which a tet counts as absurd rather than merely bad.
Definition TopoOffsetTetMesh.h:492
bool invariants(const std::vector< Tuple > &tets) override
Definition TopoOffsetTetMesh.cpp:3552
PhaseBSub
Phase B's two sub-sweeps, run in this order within every smoothing pass.
Definition TopoOffsetTetMesh.h:170
std::map< int64_t, int > m_tag_bit
Definition TopoOffsetTetMesh.h:308
bool split_tet_before(const Tuple &t) override
User specified preparations and desideratas for a tet split before changing the connectivity.
Definition EdgeSplittingTet.cpp:412
double m_spike_ordinary
AMIPS below which a tet counts as ordinary, so ordinary -> absurd is one operation's doing.
Definition TopoOffsetTetMesh.h:494
size_t phase_b_smooth()
Definition TopoOffsetTetMesh.cpp:1421
void optimize_offset(const std::filesystem::path &output_file)
optimize the offset
Definition TopoOffsetTetMesh.cpp:2970
bool vertex_is_on_region(const size_t vid) const
Is this vertex on a region boundary – a tag boundary, or the domain wall.
Definition TopoOffsetTetMesh.h:512
size_t update_band_sizing_from_tolerance()
Per-vertex band sizing update, run after Phase B. Returns the number changed.
Definition TopoOffsetTetMesh.cpp:1580
bool split_before_cells(const Tuple &edge, const std::vector< Tuple > &parents) override
Split policy that is the offset's own.
Definition EdgeSplittingTet.cpp:515
bool vertex_is_on_surface(const size_t vid) const override
Is a vertex part of the substructure.
Definition TopoOffsetTetMesh.cpp:1041
bool empty_input_complex()
check if the input complex is empty. Only valid after calling init_from_image(...)....
Definition TopoOffsetTetMesh.cpp:613
bool split_face_after(const Tuple &t) override
Compute the attributes for the added simplices.
Definition EdgeSplittingTet.cpp:322
double face_criterion_rel(const Tuple &f) const
Definition TopoOffsetTetMesh.cpp:2450
bool swap_after_cells(const std::vector< size_t > &tids, bool is_surface_flip) override
Propagate application data to the cells made by a successful topological swap.
Definition Swap.cpp:93
std::vector< std::array< double, 8 > > optimization_metrics
Definition TopoOffsetTetMesh.h:1416
double cell_quality_rel(const size_t tid) const
Definition TopoOffsetTetMesh.cpp:2427
void check_offset_within_support(const char *when) const
Stop the run if any reachable offset-surface vertex has left the potential's support.
Definition TopoOffsetTetMesh.cpp:2401
bool split_adjust_position(size_t v_new, const std::vector< Tuple > &children) override
Definition EdgeSplittingTet.cpp:578
OptPhase
Which half of the alternating optimization is running.
Definition TopoOffsetTetMesh.h:152
std::vector< Tuple > get_offset_surface_faces_for_vertex(const Tuple &t) const
offset-surface faces (see is_offset_face()) incident to vertex t
Definition Smooth.cpp:367
bool face_is_offset_surface_live(const Tuple &f) const
The band's outer surface, recomputed live rather than read from the cached class.
Definition TopoOffsetTetMesh.cpp:2164
wmtk::threading::enumerable_thread_specific< CellTag > m_swap_tag
The tag swap_after_cells writes onto the tets the swap created, chosen in before.
Definition TopoOffsetTetMesh.h:1035
double phase_b_band_gradient_linf()
L-inf over offset vertices of the gradient of each vertex's own placement objective – the energy Phas...
Definition TopoOffsetTetMesh.cpp:1407
double cell_quality(const size_t tid) const override
The quality of cell tid, and how to write it.
Definition TopoOffsetTetMesh.h:444
void write_phi_grid(const std::string &path, int n) const
Definition TopoOffsetTetMesh.cpp:3650
bool smooth_after(const Tuple &t) override
Every vertex goes through the shared smoother. Nothing is dispatched anywhere else.
Definition Smooth.cpp:93
void check_no_vertex_on_both_surfaces(const char *when) const
Definition TopoOffsetTetMesh.cpp:1189
Definition Simplex.hpp:46
Definition enumerable_thread_specific.hpp:26
bool smooth_quality_veto
Definition OptimizerParameters.h:183
What the offset needs on top of the parameters every wmtk optimizer shares.
Definition Parameters.h:20
bool debug_output_per_pass
Definition Parameters.h:45
The offset surface's residual. Every band vertex and every face sample counts toward the max and the ...
Definition TopoOffsetTetMesh.h:878
double max_at_vertex
Definition TopoOffsetTetMesh.h:885
size_t n_outside_support
Definition TopoOffsetTetMesh.h:888
Definition TopoOffsetTetMesh.h:1527
Definition TopoOffsetTetMesh.h:803
A face's shared surface tags together with the offset's own label.
Definition TopoOffsetTetMesh.h:356
Definition TopoOffsetTetMesh.h:1559
The band's placement gradient: |grad (Phi(x) - c)^2| over the offset surface – at every band vertex A...
Definition TopoOffsetTetMesh.h:915
size_t worst_vid
Definition TopoOffsetTetMesh.h:928
size_t n_skipped_inverted
Definition TopoOffsetTetMesh.h:925
double max_at_vertex
max_reachable, split by where it was measured – see the class comment.
Definition TopoOffsetTetMesh.h:920
size_t n_face_samples
How many of n_reachable came from face interiors rather than vertices.
Definition TopoOffsetTetMesh.h:922
How far each class of vertex actually gets during smoothing.
Definition TopoOffsetTetMesh.h:1275
Definition TopoOffsetTetMesh.h:981
std::atomic< long > order2
order-2 vertex into lower order
Definition TopoOffsetTetMesh.h:985
std::atomic< long > invariant
would put input-complex and offset on one vertex
Definition TopoOffsetTetMesh.h:982
std::atomic< long > class_region
region vertex may not leave its surface
Definition TopoOffsetTetMesh.h:983
std::atomic< long > sublink
substructure_link_condition refusal
Definition TopoOffsetTetMesh.h:986
std::atomic< long > class_offset
offset vertex may not leave its surface
Definition TopoOffsetTetMesh.h:984
Definition TopoOffsetTetMesh.h:1017
Why smoothing refused a vertex, one counter per site where it can say no.
Definition TopoOffsetTetMesh.h:1190
std::atomic< int > before_bbox
base smooth_before said no: on the bounding box
Definition TopoOffsetTetMesh.h:1192
std::atomic< int > before_unrounded
base smooth_before said no: could not round
Definition TopoOffsetTetMesh.h:1193
std::atomic< int > interior_attempted
reached it as an ordinary interior vertex
Definition TopoOffsetTetMesh.h:1199
std::atomic< int > attempted
smooth_before() entered
Definition TopoOffsetTetMesh.h:1191
std::atomic< int > before_phase_b_not_offset
Phase B: wrong class for this sub-sweep.
Definition TopoOffsetTetMesh.h:1195
std::atomic< int > before_phase_b_enveloped_background
Phase B: envelope-held, stencilled.
Definition TopoOffsetTetMesh.h:1196
std::atomic< int > before_on_region
input complex, frozen
Definition TopoOffsetTetMesh.h:1194
std::atomic< int > offset_attempted
reached the smoother carrying the offset term
Definition TopoOffsetTetMesh.h:1198
Definition TopoOffsetTetMesh.h:1577
Which of two mechanisms lets a wall vertex end up off its wall.
Definition TopoOffsetTetMesh.h:1307
std::atomic< int > added_deviation
... that increased off-plane deviation
Definition TopoOffsetTetMesh.h:1310
std::atomic< int > accepted_zero_tracked
... of those, with NO tracked face at it
Definition TopoOffsetTetMesh.h:1309
std::atomic< int > added_dev_zero_tracked
... and had no tracked face: mechanism (2)
Definition TopoOffsetTetMesh.h:1311
std::atomic< double > max_single_step
largest off-plane deviation one move added
Definition TopoOffsetTetMesh.h:1312
std::atomic< int > accepted
accepted smoothing moves on a vertex with wall flags
Definition TopoOffsetTetMesh.h:1308