17 int64_t collapse_type)
19 , m_coordinate_handle(coordinate)
20 , m_energy_handle(energy)
21 , m_collapse_type(collapse_type)
31 if (
mesh().top_simplex_type() ==
PT) {
36 double old_energy_max = std::numeric_limits<double>::lowest();
37 double new_energy_max = std::numeric_limits<double>::lowest();
45 const auto v1_pos = position_accessor.const_vector_attribute(v1);
48 const auto& v0_incident_tets =
50 const auto& v1_incident_tets =
54 for (
const auto& t : v1_incident_tets) {
56 assert(lv.size() == 4);
60 std::max(old_energy_max, amips_accessor.const_scalar_attribute(t.tuple()));
63 bool incident_both =
false;
64 for (
int i = 0; i < 4; ++i) {
73 if (incident_both)
continue;
76 std::array<Eigen::Vector<Rational, 3>, 4> lv_pos = {
77 {position_accessor.const_vector_attribute(lv[0]),
78 position_accessor.const_vector_attribute(lv[1]),
79 position_accessor.const_vector_attribute(lv[2]),
80 position_accessor.const_vector_attribute(lv[3])}};
82 for (
int i = 0; i < 4; ++i) {
88 lv_pos[i] = position_accessor.const_vector_attribute(v0);
100 {{lv_pos[0][0].to_double(),
101 lv_pos[0][1].to_double(),
102 lv_pos[0][2].to_double(),
103 lv_pos[1][0].to_double(),
104 lv_pos[1][1].to_double(),
105 lv_pos[1][2].to_double(),
106 lv_pos[2][0].to_double(),
107 lv_pos[2][1].to_double(),
108 lv_pos[2][2].to_double(),
109 lv_pos[3][0].to_double(),
110 lv_pos[3][1].to_double(),
111 lv_pos[3][2].to_double()}});
113 new_energy_max = std::max(new_energy_max, new_energy);
117 for (int64_t i = 0; i < 3; ++i) {
119 if (!v1_pos[i].is_rounded())
return true;
123 for (
const auto& t : v0_incident_tets) {
127 bool incident_both =
false;
128 for (
int i = 0; i < 4; ++i) {
133 incident_both =
true;
137 if (incident_both)
continue;
140 const double energy = amips_accessor.const_scalar_attribute(t.tuple());
141 old_energy_max = std::max(old_energy_max, energy);
144 new_energy_max = std::max(new_energy_max, energy);
154 const auto v0_pos = position_accessor.const_vector_attribute(v0);
157 const auto& v0_incident_tets =
159 const auto& v1_incident_tets =
163 for (
const auto& t : v0_incident_tets) {
165 assert(lv.size() == 4);
169 std::max(old_energy_max, amips_accessor.const_scalar_attribute(t.tuple()));
173 bool incident_both =
false;
174 for (
int i = 0; i < 4; ++i) {
179 incident_both =
true;
183 if (incident_both)
continue;
186 std::array<Eigen::Vector<Rational, 3>, 4> lv_pos = {
187 {position_accessor.const_vector_attribute(lv[0]),
188 position_accessor.const_vector_attribute(lv[1]),
189 position_accessor.const_vector_attribute(lv[2]),
190 position_accessor.const_vector_attribute(lv[3])}};
192 for (
int i = 0; i < 4; ++i) {
198 lv_pos[i] = position_accessor.const_vector_attribute(v1);
210 {{lv_pos[0][0].to_double(),
211 lv_pos[0][1].to_double(),
212 lv_pos[0][2].to_double(),
213 lv_pos[1][0].to_double(),
214 lv_pos[1][1].to_double(),
215 lv_pos[1][2].to_double(),
216 lv_pos[2][0].to_double(),
217 lv_pos[2][1].to_double(),
218 lv_pos[2][2].to_double(),
219 lv_pos[3][0].to_double(),
220 lv_pos[3][1].to_double(),
221 lv_pos[3][2].to_double()}});
222 new_energy_max = std::max(new_energy_max, new_energy);
226 for (int64_t i = 0; i < 3; ++i) {
228 if (!v0_pos[i].is_rounded())
return true;
232 for (
const auto& t : v1_incident_tets) {
236 bool incident_both =
false;
237 for (
int i = 0; i < 4; ++i) {
242 incident_both =
true;
246 if (incident_both)
continue;
249 const double energy = amips_accessor.const_scalar_attribute(t.tuple());
250 old_energy_max = std::max(old_energy_max, energy);
253 new_energy_max = std::max(new_energy_max, energy);
260 throw std::runtime_error(
"not implemented");
263 default:
throw std::runtime_error(
"Invalid collapse type");
267 return new_energy_max <= old_energy_max;
269 }
else if (
mesh().top_simplex_type() ==
PF) {
virtual std::vector< Tuple > orient_vertices(const Tuple &t) const =0
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
Handle that represents attributes for some mesh.
const int64_t m_collapse_type
CollapseEnergyBeforeInvariant(const Mesh &m, const attribute::TypedAttributeHandle< Rational > &coordinate, const attribute::TypedAttributeHandle< double > &energy, int64_t collapse_type=0)
const attribute::TypedAttributeHandle< Rational > m_coordinate_handle
const attribute::TypedAttributeHandle< double > m_energy_handle
bool before(const simplex::Simplex &s) const override
const Mesh & mesh() const
const Tuple & tuple() const
static Simplex vertex(const Mesh &m, const Tuple &t)
static bool equal(const Mesh &m, const Simplex &s0, const Simplex &s1)
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
double Tet_AMIPS_energy(const std::array< double, 12 > &T)
void top_dimension_cofaces(const Simplex &simplex, SimplexCollection &simplex_collection, const bool sort_and_clean)
Get all top dimension cofaces of the given simplex.
int wmtk_orient3d(const Eigen::Ref< const Eigen::Vector3< Rational >> &p0, const Eigen::Ref< const Eigen::Vector3< Rational >> &p1, const Eigen::Ref< const Eigen::Vector3< Rational >> &p2, const Eigen::Ref< const Eigen::Vector3< Rational >> &p3)
constexpr PrimitiveType PV
constexpr PrimitiveType PE