Wildmeshing Toolkit
Loading...
Searching...
No Matches
AMIPS.h
1#pragma once
2
3#include <Eigen/Core>
4
5#include <array>
6#include <cmath>
7
8namespace wmtk {
9double AMIPS_energy(const std::array<double, 12>& T);
10void AMIPS_jacobian(const std::array<double, 12>& T, Eigen::Vector3d& result_0);
11void AMIPS_hessian(const std::array<double, 12>& T, Eigen::Matrix3d& result_0);
12template <typename rational, typename dtype>
13double AMIPS_energy_rational_p3(const std::array<dtype, 12>& T)
14{
15 std::array<rational, 12> r_T;
16 for (int j = 0; j < 12; j++) r_T[j] = T[j];
17 const rational twothird = rational(2) / rational(3);
18 auto tmp = ((-r_T[1 + 2] + r_T[1 + 5]) * r_T[1 + 1] + r_T[1 + 2] * r_T[1 + 7] +
19 (r_T[1 + -1] - r_T[1 + 5]) * r_T[1 + 4] - r_T[1 + -1] * r_T[1 + 7]) *
20 r_T[1 + 9] +
21 ((r_T[1 + 2] - r_T[1 + 5]) * r_T[1 + 0] - r_T[1 + 2] * r_T[1 + 6] +
22 (-r_T[1 + -1] + r_T[1 + 5]) * r_T[1 + 3] + r_T[1 + -1] * r_T[1 + 6]) *
23 r_T[1 + 10] +
24 (-r_T[1 + 2] * r_T[1 + 7] + (-r_T[1 + 8] + r_T[1 + 5]) * r_T[1 + 4] +
25 r_T[1 + 8] * r_T[1 + 7]) *
26 r_T[1 + 0] +
27 (r_T[1 + 2] * r_T[1 + 6] + (r_T[1 + 8] - r_T[1 + 5]) * r_T[1 + 3] -
28 r_T[1 + 8] * r_T[1 + 6]) *
29 r_T[1 + 1] +
30 (r_T[1 + 3] * r_T[1 + 7] - r_T[1 + 4] * r_T[1 + 6]) * (r_T[1 + -1] - r_T[1 + 8]);
31 if (tmp == 0) return std::numeric_limits<double>::infinity();
32
33 auto res_r =
34 rational(27) / 16 * pow(tmp, -2) *
35 pow(r_T[1 + 9] * r_T[1 + 9] +
36 (-twothird * r_T[1 + 0] - twothird * r_T[1 + 3] - twothird * r_T[1 + 6]) *
37 r_T[1 + 9] +
38 r_T[1 + 10] * r_T[1 + 10] +
39 (-twothird * r_T[1 + 1] - twothird * r_T[1 + 4] - twothird * r_T[1 + 7]) *
40 r_T[1 + 10] +
41 r_T[1 + 0] * r_T[1 + 0] +
42 (-twothird * r_T[1 + 3] - twothird * r_T[1 + 6]) * r_T[1 + 0] +
43 r_T[1 + 1] * r_T[1 + 1] +
44 (-twothird * r_T[1 + 4] - twothird * r_T[1 + 7]) * r_T[1 + 1] +
45 r_T[1 + 2] * r_T[1 + 2] +
46 (-twothird * r_T[1 + -1] - twothird * r_T[1 + 8] - twothird * r_T[1 + 5]) *
47 r_T[1 + 2] +
48 r_T[1 + 3] * r_T[1 + 3] - twothird * r_T[1 + 3] * r_T[1 + 6] +
49 r_T[1 + 4] * r_T[1 + 4] - twothird * r_T[1 + 4] * r_T[1 + 7] +
50 r_T[1 + 5] * r_T[1 + 5] +
51 (-twothird * r_T[1 + -1] - twothird * r_T[1 + 8]) * r_T[1 + 5] -
52 twothird * r_T[1 + -1] * r_T[1 + 8] + r_T[1 + -1] * r_T[1 + -1] +
53 r_T[1 + 8] * r_T[1 + 8] + r_T[1 + 6] * r_T[1 + 6] + r_T[1 + 7] * r_T[1 + 7],
54 3);
55 return res_r.to_double();
56}
57template <typename rational>
58double AMIPS_energy_stable_p3(const std::array<double, 12>& T)
59{
60 auto res = AMIPS_energy(T);
61
62 if (res < 1e8 && res > 2) {
63 return std::pow(res, 3);
64 } else {
65 return AMIPS_energy_rational_p3<rational>(T);
66 }
67}
68} // namespace wmtk