Wildmeshing Toolkit
Swap23EnergyBeforeInvariant.cpp
Go to the documentation of this file.
2 #include <wmtk/Mesh.hpp>
4 #include <wmtk/utils/orient.hpp>
5 
6 namespace wmtk {
8  const Mesh& m,
10  : Invariant(m, true, false, false)
11  , m_coordinate_handle(coordinate)
12 {}
13 
15 {
16  constexpr static PrimitiveType PV = PrimitiveType::Vertex;
17  constexpr static PrimitiveType PE = PrimitiveType::Edge;
18  constexpr static PrimitiveType PF = PrimitiveType::Triangle;
19  constexpr static PrimitiveType PT = PrimitiveType::Tetrahedron;
20 
22 
23  // get the coords of the vertices
24  // input face end points
25  const Tuple v0 = t.tuple();
26  const Tuple v1 = mesh().switch_tuple(v0, PV);
27  const Tuple v2 = mesh().switch_tuples(v0, {PE, PV});
28  // other 2 vertices
29  const Tuple v3 = mesh().switch_tuples(v0, {PF, PE, PV});
30  const Tuple v4 = mesh().switch_tuples(v0, {PT, PF, PE, PV});
31 
32 
33  std::array<Eigen::Vector3<Rational>, 5> positions = {
34  {accessor.const_vector_attribute(v0),
35  accessor.const_vector_attribute(v1),
36  accessor.const_vector_attribute(v2),
37  accessor.const_vector_attribute(v3),
38  accessor.const_vector_attribute(v4)}};
39  std::array<Eigen::Vector3d, 5> positions_double = {
40  {accessor.const_vector_attribute(v0).cast<double>(),
41  accessor.const_vector_attribute(v1).cast<double>(),
42  accessor.const_vector_attribute(v2).cast<double>(),
43  accessor.const_vector_attribute(v3).cast<double>(),
44  accessor.const_vector_attribute(v4).cast<double>()}};
45 
46  std::array<std::array<int, 4>, 2> old_tets = {{{{0, 1, 2, 3}}, {{0, 1, 2, 4}}}};
47  std::array<std::array<int, 4>, 3> new_tets = {{{{3, 4, 0, 1}}, {{3, 4, 1, 2}}, {{3, 4, 2, 0}}}};
48 
49  double old_energy_max = std::numeric_limits<double>::lowest();
50  double new_energy_max = std::numeric_limits<double>::lowest();
51 
52  for (int i = 0; i < 2; ++i) {
54  positions[old_tets[i][0]],
55  positions[old_tets[i][1]],
56  positions[old_tets[i][2]],
57  positions[old_tets[i][3]]) > 0) {
59  positions_double[old_tets[i][0]][0],
60  positions_double[old_tets[i][0]][1],
61  positions_double[old_tets[i][0]][2],
62  positions_double[old_tets[i][1]][0],
63  positions_double[old_tets[i][1]][1],
64  positions_double[old_tets[i][1]][2],
65  positions_double[old_tets[i][2]][0],
66  positions_double[old_tets[i][2]][1],
67  positions_double[old_tets[i][2]][2],
68  positions_double[old_tets[i][3]][0],
69  positions_double[old_tets[i][3]][1],
70  positions_double[old_tets[i][3]][2],
71  }});
72 
73  old_energy_max = std::max(energy, old_energy_max);
74  } else {
76  positions_double[old_tets[i][1]][0],
77  positions_double[old_tets[i][1]][1],
78  positions_double[old_tets[i][1]][2],
79  positions_double[old_tets[i][0]][0],
80  positions_double[old_tets[i][0]][1],
81  positions_double[old_tets[i][0]][2],
82  positions_double[old_tets[i][2]][0],
83  positions_double[old_tets[i][2]][1],
84  positions_double[old_tets[i][2]][2],
85  positions_double[old_tets[i][3]][0],
86  positions_double[old_tets[i][3]][1],
87  positions_double[old_tets[i][3]][2],
88  }});
89 
90  old_energy_max = std::max(energy, old_energy_max);
91  }
92  }
93 
94  for (int i = 0; i < 3; ++i) {
96  positions[new_tets[i][0]],
97  positions[new_tets[i][1]],
98  positions[new_tets[i][2]],
99  positions[new_tets[i][3]]) > 0) {
101  positions_double[new_tets[i][0]][0],
102  positions_double[new_tets[i][0]][1],
103  positions_double[new_tets[i][0]][2],
104  positions_double[new_tets[i][1]][0],
105  positions_double[new_tets[i][1]][1],
106  positions_double[new_tets[i][1]][2],
107  positions_double[new_tets[i][2]][0],
108  positions_double[new_tets[i][2]][1],
109  positions_double[new_tets[i][2]][2],
110  positions_double[new_tets[i][3]][0],
111  positions_double[new_tets[i][3]][1],
112  positions_double[new_tets[i][3]][2],
113  }});
114 
115  new_energy_max = std::max(energy, new_energy_max);
116  } else {
118  positions_double[new_tets[i][1]][0],
119  positions_double[new_tets[i][1]][1],
120  positions_double[new_tets[i][1]][2],
121  positions_double[new_tets[i][0]][0],
122  positions_double[new_tets[i][0]][1],
123  positions_double[new_tets[i][0]][2],
124  positions_double[new_tets[i][2]][0],
125  positions_double[new_tets[i][2]][1],
126  positions_double[new_tets[i][2]][2],
127  positions_double[new_tets[i][3]][0],
128  positions_double[new_tets[i][3]][1],
129  positions_double[new_tets[i][3]][2],
130  }});
131 
132  new_energy_max = std::max(energy, new_energy_max);
133  }
134  }
135 
136  return old_energy_max > new_energy_max;
137 }
138 
139 } // namespace wmtk
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Definition: Mesh.hpp:967
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
const attribute::TypedAttributeHandle< Rational > m_coordinate_handle
bool before(const simplex::Simplex &t) const override
Swap23EnergyBeforeInvariant(const Mesh &m, const attribute::TypedAttributeHandle< Rational > &coordinate)
Handle that represents attributes for some mesh.
const Mesh & mesh() const
Definition: Invariant.cpp:35
const Tuple & tuple() const
Definition: Simplex.hpp:53
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
double Tet_AMIPS_energy(const std::array< double, 12 > &T)
Definition: amips.cpp:380
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)
Definition: orient.cpp:75
Definition: Accessor.hpp:6
constexpr PrimitiveType PV
constexpr PrimitiveType PE