From 8d0e84788189748d9e906cc7f807507a3cb4b2ef Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Fri, 31 Jul 2026 10:12:30 -0700 Subject: [PATCH] Support Eigen 5: reimplement removed internal::make_coherent Eigen 5.0 removed Eigen::internal::make_coherent from unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h, which AutomaticDifferentiation.hh references in the pow(AutoDiffScalar, AutoDiffScalar) overload. Because the call is qualified, name lookup happens at template definition time, so any TU including this header fails to compile against Eigen >= 5 even if pow is never instantiated (this also breaks all of MeshFEMSparse, whose SparseMatrices.hh includes this header). Reimplement it with the Eigen 3.4 semantics behind a version guard. Note Eigen 5 moved to semantic versioning: EIGEN_WORLD_VERSION remains 3 forever and the new major version lives in EIGEN_MAJOR_VERSION. --- .../MeshFEMCore/AutomaticDifferentiation.hh | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/lib/MeshFEMCore/AutomaticDifferentiation.hh b/src/lib/MeshFEMCore/AutomaticDifferentiation.hh index bfea387..fc3ecd5 100644 --- a/src/lib/MeshFEMCore/AutomaticDifferentiation.hh +++ b/src/lib/MeshFEMCore/AutomaticDifferentiation.hh @@ -4,6 +4,33 @@ #include #include +// Eigen 5 removed Eigen::internal::make_coherent from AutoDiffScalar.h; +// reimplement it with the Eigen 3.4 semantics: if exactly one of the two +// derivative vectors is empty, resize it to match the other and zero it. +// (Note: Eigen 5 moved to semantic versioning — EIGEN_WORLD_VERSION remains 3 +// forever and the major version lives in EIGEN_MAJOR_VERSION.) +#if EIGEN_MAJOR_VERSION >= 5 +namespace Eigen { +namespace internal { + template + inline void make_coherent(const DerTypeA &a, const DerTypeB &b) { + // Eigen 3.4's implementation const-casts too (the derivatives are + // semantically mutable scratch space of the AutoDiffScalar pair). + DerTypeA &a_ref = const_cast(a); + DerTypeB &b_ref = const_cast(b); + if (a_ref.size() == 0 && b_ref.size() != 0) { + a_ref.resize(b_ref.size()); + a_ref.setZero(); + } + else if (b_ref.size() == 0 && a_ref.size() != 0) { + b_ref.resize(a_ref.size()); + b_ref.setZero(); + } + } +} // namespace internal +} // namespace Eigen +#endif + namespace MeshFEM { using ADReal = Eigen::AutoDiffScalar>;