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) {