From a06a513ebe16378968441fa012a9f61d69bb407e Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 2 Sep 2026 14:09:26 +0200 Subject: [PATCH 1/6] explicit position vector in getPotentialEnergy --- .../fem/elastic/HexahedronFEMForceFieldAndMass.h | 9 ++------- .../tensormass/TetrahedralTensorMassForceField.h | 7 +------ .../tensormass/TetrahedralTensorMassForceField.inl | 4 +--- .../Core/src/sofa/core/behavior/BaseForceField.cpp | 5 +++++ .../Core/src/sofa/core/behavior/BaseForceField.h | 11 +++++++---- .../Core/src/sofa/core/behavior/ForceField.h | 2 +- .../Core/src/sofa/core/behavior/ForceField.inl | 7 +++++-- Sofa/framework/Core/src/sofa/core/behavior/Mass.h | 3 ++- Sofa/framework/Core/src/sofa/core/behavior/Mass.inl | 7 +++++-- .../sofa/core/behavior/MixedInteractionForceField.h | 2 +- .../sofa/core/behavior/MixedInteractionForceField.inl | 8 ++++++-- .../sofa/core/behavior/PairInteractionForceField.h | 2 +- .../sofa/core/behavior/PairInteractionForceField.inl | 8 ++++++-- Sofa/framework/Simulation/Core/test/Visitor_test.cpp | 4 ++-- 14 files changed, 45 insertions(+), 34 deletions(-) diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h index d6e8b1531a1..ae9160a0161 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h @@ -97,14 +97,9 @@ class HexahedronFEMForceFieldAndMass : virtual public core::behavior::Mass::initNeighbourhoodPoints() {} template -SReal TetrahedralTensorMassForceField::getPotentialEnergy(const core::MechanicalParams* /* mparams */) const +SReal TetrahedralTensorMassForceField::getPotentialEnergy(const core::MechanicalParams* /* mparams */, const DataVecCoord& x) const { SCOPED_TIMER("getPotentialEnergy"); - const VecCoord& x = this->mstate->read(core::vec_id::read_access::position)->getValue(); - SReal energy=0; unsigned int v0,v1; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.cpp b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.cpp index 00237553892..827d4bf05c1 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.cpp +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.cpp @@ -52,6 +52,11 @@ void BaseForceField::addMBKdx(const MechanicalParams* mparams, MultiVecDerivId d } } +SReal BaseForceField::getPotentialEnergy(const MechanicalParams* mparams) const +{ + return this->getPotentialEnergy(mparams, mparams->x()); +} + void BaseForceField::addBToMatrix(const MechanicalParams* /*mparams*/, const sofa::core::behavior::MultiMatrixAccessor* /*matrix*/) { } diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h index 6bd74516017..1bf959b900c 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h @@ -136,10 +136,13 @@ class SOFA_CORE_API BaseForceField : public virtual StateAccessor /// \brief Get the potential energy associated to this ForceField during the /// last call of addForce( const MechanicalParams* mparams ); - /// - /// Used to estimate the total energy of the system by some - /// post-stabilization techniques. - virtual SReal getPotentialEnergy( const MechanicalParams* mparams = mechanicalparams::defaultInstance() ) const=0; + /// \note Used to estimate the total energy of the system by some post-stabilization techniques. + /// \param mparams + /// \param xId The potential energy is evaluated on this vector of generalized coordinates + virtual SReal getPotentialEnergy(const MechanicalParams* mparams, + ConstMultiVecCoordId xId) const = 0; + + virtual SReal getPotentialEnergy( const MechanicalParams* mparams = mechanicalparams::defaultInstance() ) const final; /// @} diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h index 26d7b07d58a..e23e73b0b73 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h @@ -116,7 +116,7 @@ class ForceField : public BaseForceField, public virtual SingleStateAccessor::addDForce(const MechanicalParams* mparams, MultiVecD } template -SReal ForceField::getPotentialEnergy(const MechanicalParams* mparams) const +SReal ForceField::getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const { if (this->mstate) - return getPotentialEnergy(mparams, *mparams->readX(this->mstate.get())); + { + const DataVecCoord* x = xId[this->mstate.get()].read(); assert(x); + return getPotentialEnergy(mparams, *x); + } return 0; } diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h index 1dec7f93119..1cad0f8dc71 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h @@ -103,8 +103,9 @@ class Mass : virtual public ForceField, public BaseMass /// /// This method retrieves the positions vector and call the internal /// getPotentialEnergy(const MechanicalParams*, const VecCoord&) method implemented by the component. - SReal getPotentialEnergy( const MechanicalParams* mparams) const override; + SReal getPotentialEnergy( const MechanicalParams* mparams, ConstMultiVecCoordId xId) const override; SReal getPotentialEnergy( const MechanicalParams* mparams, const DataVecCoord& x ) const override; + using BaseForceField::getPotentialEnergy; /// $ m = ( Mv, cross(x,Mv)+Iw ) $ diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl index 78041353ccc..6f79afc33d0 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl @@ -120,10 +120,13 @@ SReal Mass::getKineticEnergy(const MechanicalParams* /*mparams*/, con template -SReal Mass::getPotentialEnergy(const MechanicalParams* mparams) const +SReal Mass::getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const { if (this->mstate) - return getPotentialEnergy(mparams /* PARAMS FIRST */, *mparams->readX(this->mstate.get())); + { + const DataVecCoord* x = xId[this->mstate.get()].read(); assert(x); + return getPotentialEnergy(mparams, *x); + } return 0.0; } diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h index 59a898eaf56..5017b486947 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h @@ -106,7 +106,7 @@ class MixedInteractionForceField : public BaseInteractionForceField, public Pair /// This method retrieves the x vector from the MechanicalState and call /// the internal getPotentialEnergy(const VecCoord&,const VecCoord&) method implemented by /// the component. - SReal getPotentialEnergy(const MechanicalParams* mparams) const override; + SReal getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const override; /// Given the current position and velocity states, update the current force /// vector by computing and adding the forces associated with this diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.inl b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.inl index 2382824d1ca..a711daf4bae 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.inl +++ b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.inl @@ -75,10 +75,14 @@ void MixedInteractionForceField::addDForce(const Mechani template -SReal MixedInteractionForceField::getPotentialEnergy(const MechanicalParams* mparams) const +SReal MixedInteractionForceField::getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const { if (this->mstate1 && this->mstate2) - return getPotentialEnergy(mparams, *mparams->readX(this->mstate1.get()),*mparams->readX(this->mstate2.get())); + { + const DataVecCoord1* x1 = xId[this->mstate1.get()].read(); assert(x1); + const DataVecCoord2* x2 = xId[this->mstate2.get()].read(); assert(x2); + return getPotentialEnergy(mparams, *x1, *x2); + } else return 0; } diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h index d4fc66b7ad1..db045310ab9 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h @@ -138,7 +138,7 @@ class PairInteractionForceField : public BaseInteractionForceField, public PairS /// This method retrieves the x vector from the MechanicalState and call /// the internal getPotentialEnergy(const VecCoord&,const VecCoord&) method implemented by /// the component. - SReal getPotentialEnergy(const MechanicalParams* mparams) const override; + SReal getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const override; /// Get the potential energy associated to this ForceField. /// diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.inl b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.inl index 15d6341dab9..0575440c3f3 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.inl +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.inl @@ -81,12 +81,16 @@ void PairInteractionForceField::addDForce(const MechanicalParams* mpa } template -SReal PairInteractionForceField::getPotentialEnergy(const MechanicalParams* mparams) const +SReal PairInteractionForceField::getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const { auto state1 = this->mstate1.get(); auto state2 = this->mstate2.get(); if (state1 && state2) - return getPotentialEnergy(mparams, *mparams->readX(state1),*mparams->readX(state2)); + { + const DataVecCoord* x1 = xId[state1].read(); assert(x1); + const DataVecCoord* x2 = xId[state2].read(); assert(x2); + return getPotentialEnergy(mparams, *x1, *x2); + } else return 0.0; } diff --git a/Sofa/framework/Simulation/Core/test/Visitor_test.cpp b/Sofa/framework/Simulation/Core/test/Visitor_test.cpp index 4443f2cef00..11a2ca3a735 100644 --- a/Sofa/framework/Simulation/Core/test/Visitor_test.cpp +++ b/Sofa/framework/Simulation/Core/test/Visitor_test.cpp @@ -100,7 +100,7 @@ class TestForceField : public core::behavior::BaseForceField SOFA_UNUSED(mparams); SOFA_UNUSED(dfId); } - SReal getPotentialEnergy(const core::MechanicalParams* mparams) const override + SReal getPotentialEnergy(const core::MechanicalParams* mparams, core::ConstMultiVecCoordId dxId) const override { SOFA_UNUSED(mparams); return {}; @@ -186,7 +186,7 @@ class TestInteractionForceField : public core::behavior::BaseInteractionForceFie SOFA_UNUSED(mparams); SOFA_UNUSED(dfId); } - SReal getPotentialEnergy(const core::MechanicalParams* mparams) const override + SReal getPotentialEnergy(const core::MechanicalParams* mparams, core::ConstMultiVecCoordId) const override { SOFA_UNUSED(mparams); return {}; From ffcfaabeaf2f6527f0ab7a9bf3752add348f64bd Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 2 Sep 2026 14:12:21 +0200 Subject: [PATCH 2/6] deprecate the old overload --- .../framework/Core/src/sofa/core/behavior/BaseForceField.h | 1 + Sofa/framework/Core/src/sofa/core/config.h.in | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h index 1bf959b900c..b6dcfc1938e 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseForceField.h @@ -142,6 +142,7 @@ class SOFA_CORE_API BaseForceField : public virtual StateAccessor virtual SReal getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const = 0; + SOFA_ATTRIBUTE_DEPRECATED__GETPOTENTIALENERGY_OVERLOAD() virtual SReal getPotentialEnergy( const MechanicalParams* mparams = mechanicalparams::defaultInstance() ) const final; /// @} diff --git a/Sofa/framework/Core/src/sofa/core/config.h.in b/Sofa/framework/Core/src/sofa/core/config.h.in index b2824481f2f..d8c3957d27f 100644 --- a/Sofa/framework/Core/src/sofa/core/config.h.in +++ b/Sofa/framework/Core/src/sofa/core/config.h.in @@ -139,3 +139,10 @@ SOFA_ATTRIBUTE_DEPRECATED("v26.12", "v27.12", "Use BaseContext instead of Contex #define SOFA_ATTRIBUTE_DEPRECATED__ADDFORCE_OVERLOAD() \ SOFA_ATTRIBUTE_DEPRECATED("v26.12", "v27.06", "addForce must be called by providing the position vector.") #endif + +#ifdef SOFA_BUILD_SOFA_CORE +#define SOFA_ATTRIBUTE_DEPRECATED__GETPOTENTIALENERGY_OVERLOAD() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__GETPOTENTIALENERGY_OVERLOAD() \ + SOFA_ATTRIBUTE_DEPRECATED("v26.12", "v27.06", "getPotentialEnergy must be called by providing the position vector.") +#endif From 16c04c7ec9cba6f2bd47e769b07f78ff179d8cbc Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 2 Sep 2026 14:33:27 +0200 Subject: [PATCH 3/6] explicit the x vector at the call sites --- .../backward/VariationalSymplecticSolver.cpp | 0 .../framework/Core/src/sofa/core/behavior/Mass.inl | 12 ++++++++---- .../src/sofa/simulation/MechanicalOperations.cpp | 11 ++++++++--- .../src/sofa/simulation/MechanicalOperations.h | 2 ++ .../Core/src/sofa/simulation/config.h.in | 14 ++++++++++++++ .../MechanicalComputeEnergyVisitor.cpp | 11 ++++++++--- .../MechanicalComputeEnergyVisitor.h | 8 ++++++-- 7 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl index 6f79afc33d0..eb4b291243b 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl @@ -220,10 +220,14 @@ void Mass::exportGnuplot(const MechanicalParams* mparams, SReal time) { if (m_gnuplotFileEnergy!=nullptr) { - (*m_gnuplotFileEnergy) << time <<"\t"<< this->getKineticEnergy(mparams) - <<"\t"<< this->getPotentialEnergy(mparams) - <<"\t"<< this->getPotentialEnergy(mparams) - +this->getKineticEnergy(mparams)<< std::endl; + assert(mparams); + auto xId = mparams->x(); + const auto kineticEnergy = this->getKineticEnergy(mparams); + const auto potentialEnergy = this->getPotentialEnergy(mparams, xId); + (*m_gnuplotFileEnergy) << time <<"\t"<< kineticEnergy + <<"\t"<< potentialEnergy + <<"\t"<< potentialEnergy + +kineticEnergy<< std::endl; } } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.cpp index 671ecef4e21..79d700ab702 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.cpp @@ -194,17 +194,22 @@ void MechanicalOperations::projectPosition(core::MultiVecCoordId x, SReal time) executeVisitor( MechanicalProjectPositionVisitor(&mparams, time, x) ); } -/// Apply projective constraints to the given velocity vector -void MechanicalOperations::computeEnergy(SReal &kineticEnergy, SReal &potentialEnergy) +void MechanicalOperations::computeEnergy(core::ConstMultiVecCoordId xId, + SReal& kineticEnergy, SReal& potentialEnergy) { kineticEnergy = 0; potentialEnergy = 0; - MechanicalComputeEnergyVisitor energyVisitor(&mparams); + MechanicalComputeEnergyVisitor energyVisitor(&mparams, xId); executeVisitor(&energyVisitor); kineticEnergy = energyVisitor.getKineticEnergy(); potentialEnergy = energyVisitor.getPotentialEnergy(); } +void MechanicalOperations::computeEnergy(SReal &kineticEnergy, SReal &potentialEnergy) +{ + computeEnergy(mparams.x(), kineticEnergy, potentialEnergy); +} + /// Apply projective constraints to the given velocity vector void MechanicalOperations::projectVelocity(core::MultiVecDerivId v, SReal time) { diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.h index ea8d60fb3ad..eebd1893dbb 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/MechanicalOperations.h @@ -82,6 +82,8 @@ class SOFA_SIMULATION_CORE_API MechanicalOperations void integrateVelocity(core::MultiVecDerivId res, core::ConstMultiVecCoordId x, core::ConstMultiVecDerivId v, SReal dt); ///< res = x + v.dt void accFromF(core::MultiVecDerivId a, core::ConstMultiVecDerivId f); ///< a = M^-1 . f /// Compute Energy + void computeEnergy(core::ConstMultiVecCoordId xId, SReal &kineticEnergy, SReal &potentialEnergy); + SOFA_ATTRIBUTE_DEPRECATED__COMPUTEENERGY_OVERLOAD() void computeEnergy(SReal &kineticEnergy, SReal &potentialEnergy); /// Compute the current force (given the latest propagated position and velocity) void computeForce(core::MultiVecDerivId result, core::ConstMultiVecCoordId xId, core::ConstMultiVecDerivId vId, diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in index 82a17d1652c..27524378019 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in @@ -270,3 +270,17 @@ #define SOFA_ATTRIBUTE_DEPRECATED__COMPUTEFORCE_OVERLOAD() \ SOFA_ATTRIBUTE_DISABLED("v26.12", "v27.06", "computeForce must be used by providing the x and v vectors.") #endif + +#ifdef SOFA_BUILD_SOFA_SIMULATION_CORE +#define SOFA_ATTRIBUTE_DEPRECATED__MECHANICALCOMPUTEENERGYVISITOR_CONSTRUCTOR_OVERLOAD() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__MECHANICALCOMPUTEENERGYVISITOR_CONSTRUCTOR_OVERLOAD() \ + SOFA_ATTRIBUTE_DISABLED("v26.12", "v27.06", "Constructor must be used by providing the x vector.") +#endif + +#ifdef SOFA_BUILD_SOFA_SIMULATION_CORE +#define SOFA_ATTRIBUTE_DEPRECATED__COMPUTEENERGY_OVERLOAD() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__COMPUTEENERGY_OVERLOAD() \ + SOFA_ATTRIBUTE_DISABLED("v26.12", "v27.06", "computeEnergy must be used by providing the x vector.") +#endif diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.cpp index 4659d4e9d98..218b6e5e28a 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.cpp @@ -29,11 +29,16 @@ namespace sofa::simulation::mechanicalvisitor MechanicalComputeEnergyVisitor::MechanicalComputeEnergyVisitor(const sofa::core::MechanicalParams* mparams) : sofa::simulation::MechanicalVisitor(mparams) - , m_kineticEnergy(0.) - , m_potentialEnergy(0.) { + assert(mparams); + m_xId = mparams->x(); } +MechanicalComputeEnergyVisitor::MechanicalComputeEnergyVisitor( + const sofa::core::MechanicalParams* mparams, core::ConstMultiVecCoordId xId) + : sofa::simulation::MechanicalVisitor(mparams) + , m_xId(xId) +{} MechanicalComputeEnergyVisitor::~MechanicalComputeEnergyVisitor() { @@ -59,7 +64,7 @@ Visitor::Result MechanicalComputeEnergyVisitor::fwdMass(simulation::Node* /*node /// Process the BaseForceField Visitor::Result MechanicalComputeEnergyVisitor::fwdForceField(simulation::Node* /*node*/, sofa::core::behavior::BaseForceField* f) { - m_potentialEnergy += (SReal)f->getPotentialEnergy(); + m_potentialEnergy += (SReal)f->getPotentialEnergy(mparams, m_xId); return RESULT_CONTINUE; } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.h index 4820c18dad2..1d15585b0c8 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/mechanicalvisitor/MechanicalComputeEnergyVisitor.h @@ -35,12 +35,16 @@ Compute the amount of mechanical energy */ class SOFA_SIMULATION_CORE_API MechanicalComputeEnergyVisitor : public sofa::simulation::MechanicalVisitor { - SReal m_kineticEnergy; - SReal m_potentialEnergy; + SReal m_kineticEnergy {}; + SReal m_potentialEnergy {}; + core::ConstMultiVecCoordId m_xId; public: + SOFA_ATTRIBUTE_DEPRECATED__MECHANICALCOMPUTEENERGYVISITOR_CONSTRUCTOR_OVERLOAD() MechanicalComputeEnergyVisitor(const sofa::core::MechanicalParams* mparams); + MechanicalComputeEnergyVisitor(const sofa::core::MechanicalParams* mparams, core::ConstMultiVecCoordId xId); + ~MechanicalComputeEnergyVisitor() override; SReal getKineticEnergy(); From fdae297265582c68ee0170c13debec6185e369c6 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 25 Sep 2026 14:10:40 +0200 Subject: [PATCH 4/6] remove redundant override --- Sofa/framework/Core/src/sofa/core/behavior/Mass.h | 5 ----- Sofa/framework/Core/src/sofa/core/behavior/Mass.inl | 12 ------------ 2 files changed, 17 deletions(-) diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h index 1cad0f8dc71..6f512951dea 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h @@ -99,11 +99,6 @@ class Mass : virtual public ForceField, public BaseMass SReal getKineticEnergy( const MechanicalParams* mparams) const override; virtual SReal getKineticEnergy( const MechanicalParams* mparams, const DataVecDeriv& v) const; - /// $ e = M g x $ - /// - /// This method retrieves the positions vector and call the internal - /// getPotentialEnergy(const MechanicalParams*, const VecCoord&) method implemented by the component. - SReal getPotentialEnergy( const MechanicalParams* mparams, ConstMultiVecCoordId xId) const override; SReal getPotentialEnergy( const MechanicalParams* mparams, const DataVecCoord& x ) const override; using BaseForceField::getPotentialEnergy; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl index eb4b291243b..af7659392ba 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.inl @@ -118,18 +118,6 @@ SReal Mass::getKineticEnergy(const MechanicalParams* /*mparams*/, con return 0.0; } - -template -SReal Mass::getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const -{ - if (this->mstate) - { - const DataVecCoord* x = xId[this->mstate.get()].read(); assert(x); - return getPotentialEnergy(mparams, *x); - } - return 0.0; -} - template SReal Mass::getPotentialEnergy(const MechanicalParams* /*mparams*/, const DataVecCoord& /*x*/) const { From 6af077ec0a876e4487d699abffd855a488d02c6e Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 25 Sep 2026 14:13:33 +0200 Subject: [PATCH 5/6] fix TetrahedralTensorMassForceField --- .../TetrahedralTensorMassForceField.inl | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl index f16a196fb86..92f0410f321 100644 --- a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl +++ b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl @@ -224,7 +224,7 @@ void TetrahedralTensorMassForceField::applyTetrahedronDestruction(con } -template +template TetrahedralTensorMassForceField::TetrahedralTensorMassForceField() : _initialPoints(0) , updateMatrix(true) @@ -238,12 +238,12 @@ TetrahedralTensorMassForceField::TetrahedralTensorMassForceField() { } -template +template TetrahedralTensorMassForceField::~TetrahedralTensorMassForceField() { } -template void +template void TetrahedralTensorMassForceField::init() { this->Inherited::init(); @@ -353,25 +353,23 @@ SReal TetrahedralTensorMassForceField::getPotentialEnergy(const core: Deriv force,dp; Deriv dp0,dp1; - for(int i=0; igetEdge(i)[0]; - v1=m_topology->getEdge(i)[1]; - dp0=x[v0]-_initialPoints[v0]; - dp1=x[v1]-_initialPoints[v1]; - dp = dp1-dp0; - force=einfo->DfDx*dp; - energy+=dot(force,dp1); - force=einfo->DfDx.multTranspose(dp); - energy-=dot(force,dp0); + einfo = &edgeInf[i]; + v0 = m_topology->getEdge(i)[0]; + v1 = m_topology->getEdge(i)[1]; + dp0 = xAccessor[v0] - _initialPoints[v0]; + dp1 = xAccessor[v1] - _initialPoints[v1]; + dp = dp1 - dp0; + force = einfo->DfDx * dp; + energy += dot(force, dp1); + force = einfo->DfDx.multTranspose(dp); + energy -= dot(force, dp0); } - energy/=-2.0; - - msg_info() << "energy="< From 674701160fa57423d94773db647ec2e4f49a9b24 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 25 Sep 2026 14:48:18 +0200 Subject: [PATCH 6/6] fix compilation --- Sofa/framework/Core/src/sofa/core/behavior/BaseMass.cpp | 5 +++++ Sofa/framework/Core/src/sofa/core/behavior/BaseMass.h | 5 ++++- Sofa/framework/Core/src/sofa/core/behavior/ForceField.h | 2 +- Sofa/framework/Core/src/sofa/core/behavior/Mass.h | 1 + .../Core/src/sofa/core/behavior/PairInteractionForceField.h | 1 + Sofa/framework/Simulation/Core/test/Visitor_test.cpp | 2 +- 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.cpp b/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.cpp index 340ee5a4ae9..2260fef9f02 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.cpp +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.cpp @@ -49,6 +49,11 @@ bool BaseMass::removeInNode( objectmodel::BaseNode* node ) return true; } +SReal BaseMass::getPotentialEnergy(const MechanicalParams* mparams) const +{ + return this->getPotentialEnergy(mparams, mparams->x()); +} + void BaseMass::buildMassMatrix(sofa::core::behavior::MassMatrixAccumulator* matrices) { static std::set hasEmittedWarning; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.h b/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.h index d2e28de59b5..258622f10d5 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseMass.h @@ -72,7 +72,10 @@ class SOFA_CORE_API BaseMass : public virtual StateAccessor /// vMv/2 virtual SReal getKineticEnergy(const MechanicalParams* mparams = mechanicalparams::defaultInstance()) const = 0; /// Mgx - virtual SReal getPotentialEnergy(const MechanicalParams* mparams = mechanicalparams::defaultInstance()) const = 0; + virtual SReal getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const = 0; + + SOFA_ATTRIBUTE_DEPRECATED__GETPOTENTIALENERGY_OVERLOAD() + virtual SReal getPotentialEnergy(const MechanicalParams* mparams = mechanicalparams::defaultInstance()) const final; /// (Mv,xMv+Iw) (linear and angular momenta against world origin) virtual type::Vec6 getMomentum(const MechanicalParams* mparams = mechanicalparams::defaultInstance()) const = 0; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h index e23e73b0b73..7c598c1547a 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h @@ -119,7 +119,7 @@ class ForceField : public BaseForceField, public virtual SingleStateAccessor, public BaseMass SReal getKineticEnergy( const MechanicalParams* mparams) const override; virtual SReal getKineticEnergy( const MechanicalParams* mparams, const DataVecDeriv& v) const; + SReal getPotentialEnergy( const MechanicalParams* mparams, ConstMultiVecCoordId x) const override { return ForceField::getPotentialEnergy(mparams, x); } SReal getPotentialEnergy( const MechanicalParams* mparams, const DataVecCoord& x ) const override; using BaseForceField::getPotentialEnergy; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h index db045310ab9..1c7670e57c3 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h @@ -139,6 +139,7 @@ class PairInteractionForceField : public BaseInteractionForceField, public PairS /// the internal getPotentialEnergy(const VecCoord&,const VecCoord&) method implemented by /// the component. SReal getPotentialEnergy(const MechanicalParams* mparams, ConstMultiVecCoordId xId) const override; + using BaseForceField::getPotentialEnergy; /// Get the potential energy associated to this ForceField. /// diff --git a/Sofa/framework/Simulation/Core/test/Visitor_test.cpp b/Sofa/framework/Simulation/Core/test/Visitor_test.cpp index 11a2ca3a735..751625162b1 100644 --- a/Sofa/framework/Simulation/Core/test/Visitor_test.cpp +++ b/Sofa/framework/Simulation/Core/test/Visitor_test.cpp @@ -136,7 +136,7 @@ class TestMass : public core::behavior::BaseMass SOFA_UNUSED(mparams); return {}; } - SReal getPotentialEnergy(const core::MechanicalParams* mparams) const override + SReal getPotentialEnergy(const core::MechanicalParams* mparams, core::ConstMultiVecCoordId x) const override { SOFA_UNUSED(mparams); return {};