diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/CMakeLists.txt b/Sofa/Component/SolidMechanics/FEM/HyperElastic/CMakeLists.txt
index 12a1833d4ad..8cec2c82e59 100644
--- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/CMakeLists.txt
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/CMakeLists.txt
@@ -6,6 +6,12 @@ set(SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR "src/sofa/component/so
set(HEADER_FILES
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/config.h.in
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/init.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticityFEMForceField.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticityFEMForceField.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticMaterial.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/PK2HyperelasticMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/PK2HyperelasticMaterial.inl
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/StandardTetrahedralFEMForceField.h
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/StandardTetrahedralFEMForceField.inl
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/TetrahedronHyperelasticityFEMDrawing.h
@@ -22,19 +28,45 @@ set(HEADER_FILES
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/material/StableNeoHookean.h
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/material/STVenantKirchhoff.h
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/material/VerondaWestman.h
+
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/impl/MajorSymmetric4Tensor.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/impl/Strain.h
+
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/LinearMechanicalParametersComponent.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/LinearMechanicalParametersComponent.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/MooneyRivlinMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/MooneyRivlinMaterial.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/NeoHookeanMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/NeoHookeanMaterial.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/OgdenMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/OgdenMaterial.inl
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/StVenantKirchhoffMaterial.h
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/StVenantKirchhoffMaterial.inl
)
set(SOURCE_FILES
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/init.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/PK2HyperelasticMaterial.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticityFEMForceField.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/HyperelasticMaterial.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/StandardTetrahedralFEMForceField.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/TetrahedronHyperelasticityFEMForceField.cpp
${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/material/PlasticMaterial.cpp
+
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/LinearMechanicalParametersComponent.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/MooneyRivlinMaterial.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/NeoHookeanMaterial.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/OgdenMaterial.cpp
+ ${SOFACOMPONENTSOLIDMECHANICSFEMHYPERELASTIC_SOURCE_DIR}/hyperelasticmaterials/StVenantKirchhoffMaterial.cpp
)
-sofa_find_package(Sofa.Simulation.Core REQUIRED)
+sofa_find_package(Sofa.Simulation.Core Sofa.Component.SolidMechanics.FEM.Elastic REQUIRED)
add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
-target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Core)
+target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Core Sofa.Component.SolidMechanics.FEM.Elastic)
sofa_create_package_with_targets(
PACKAGE_NAME ${PROJECT_NAME}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/Sofa.Component.SolidMechanics.FEM.HyperElasticConfig.cmake.in b/Sofa/Component/SolidMechanics/FEM/HyperElastic/Sofa.Component.SolidMechanics.FEM.HyperElasticConfig.cmake.in
index 5e94811a2f4..e174907f90b 100644
--- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/Sofa.Component.SolidMechanics.FEM.HyperElasticConfig.cmake.in
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/Sofa.Component.SolidMechanics.FEM.HyperElasticConfig.cmake.in
@@ -5,6 +5,7 @@
find_package(Sofa.Config QUIET REQUIRED)
sofa_find_package(Sofa.Simulation.Core QUIET REQUIRED)
+sofa_find_package(Sofa.Component.SolidMechanics.FEM.Elastic QUITE REQUIRED)
sofa_find_package(Sofa.Component.Topology.Container.Grid QUIET REQUIRED)
if(NOT TARGET @PROJECT_NAME@)
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.cpp b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.cpp
new file mode 100644
index 00000000000..a9cfa931fe4
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.cpp
@@ -0,0 +1,34 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#define ELASTICITY_COMPONENT_HYPERELASTIC_MATERIAL_CPP
+
+#include
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.h
new file mode 100644
index 00000000000..ba253a4bc77
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+#if !defined(ELASTICITY_COMPONENT_HYPERELASTIC_MATERIAL_CPP)
+#include
+#endif
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+class HyperelasticMaterial : public virtual sofa::core::objectmodel::BaseObject
+{
+public:
+ SOFA_ABSTRACT_CLASS(HyperelasticMaterial, sofa::core::objectmodel::BaseObject);
+ using DataTypes = TDataTypes;
+
+protected:
+ using Real = sofa::Real_t;
+
+ static constexpr sofa::Size spatial_dimensions = DataTypes::spatial_dimensions;
+
+ using DeformationGradient = sofa::type::Mat;
+ using RightCauchyGreenTensor = sofa::type::Mat;
+ using StressTensor = sofa::type::Mat;
+ using ElasticityTensor = sofa::type::FullySymmetric4Tensor;
+ using TangentModulus = MajorSymmetric4Tensor;
+
+public:
+ void init() override;
+
+ /**
+ * Computes the First Piola-Kirchhoff stress tensor for a given deformation gradient.
+ *
+ * It corresponds to the derivative of the strain energy density function w.r.t. deformation
+ * gradient.
+ */
+ virtual StressTensor firstPiolaKirchhoffStress(Strain& strain) = 0;
+
+ /**
+ * Compute the jacobian of the first Piola-Kirchhoff stress tensor with respect to the
+ * deformation gradient.
+ *
+ * It is called the material tangent modulus.
+ */
+ virtual TangentModulus materialTangentModulus(Strain& strain) = 0;
+
+};
+
+#if !defined(ELASTICITY_COMPONENT_HYPERELASTIC_MATERIAL_CPP)
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticMaterial;
+#endif
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.inl
new file mode 100644
index 00000000000..225513ef0c0
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticMaterial.inl
@@ -0,0 +1,39 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+void HyperelasticMaterial::init()
+{
+ sofa::core::objectmodel::BaseObject::init();
+
+ if (!this->isComponentStateInvalid())
+ {
+ this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid);
+ }
+}
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.cpp b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.cpp
new file mode 100644
index 00000000000..046a8988450
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.cpp
@@ -0,0 +1,57 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#define ELASTICITY_COMPONENT_HYPERLASTICITY_FEM_FORCE_FIELD_CPP
+
+#include
+
+#include
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+void registerHyperelasticityFEMForceField(sofa::core::ObjectFactory* factory)
+{
+ factory->registerObjects(sofa::core::ObjectRegistrationData("Hyperelasticity")
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ .add< HyperelasticityFEMForceField >()
+ );
+}
+
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.h
new file mode 100644
index 00000000000..6056675d182
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.h
@@ -0,0 +1,164 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+#include
+
+#if !defined(ELASTICITY_COMPONENT_ELEMENT_HYPERLASTICITY_FEM_FORCE_FIELD_CPP)
+#include
+#endif
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+class HyperelasticityFEMForceField :
+ public sofa::component::solidmechanics::fem::elastic::FEMForceField
+{
+public:
+ SOFA_CLASS(
+ SOFA_TEMPLATE2(HyperelasticityFEMForceField, TDataTypes, TElementType),
+ SOFA_TEMPLATE2(sofa::component::solidmechanics::fem::elastic::FEMForceField, TDataTypes, TElementType));
+
+ using DataTypes = TDataTypes;
+
+private:
+ using DataVecCoord = sofa::DataVecDeriv_t;
+ using DataVecDeriv = sofa::DataVecDeriv_t;
+ using VecCoord = sofa::VecCoord_t;
+ using VecDeriv = sofa::VecDeriv_t;
+ using Coord = sofa::Coord_t;
+ using Deriv = sofa::Deriv_t;
+ using Real = sofa::Real_t;
+
+ using FiniteElement = sofa::fem::FiniteElement;
+
+ static constexpr sofa::Size spatial_dimensions = TDataTypes::spatial_dimensions;
+ static constexpr sofa::Size NumberOfNodesInElement = TElementType::NumberOfNodes;
+ static constexpr sofa::Size NumberOfDofsInElement = NumberOfNodesInElement * spatial_dimensions;
+ static constexpr sofa::Size TopologicalDimension = FiniteElement::TopologicalDimension;
+ static constexpr sofa::Size NumberOfQuadraturePoints = FiniteElement::quadraturePoints().size();
+
+ using DeformationGradient = sofa::type::Mat;
+
+ /// the type of the element stiffness matrix
+ using ElementStiffness = sofa::type::Mat<
+ TElementType::NumberOfNodes * DataTypes::spatial_dimensions,
+ TElementType::NumberOfNodes * DataTypes::spatial_dimensions,
+ sofa::Real_t
+ >;
+
+public:
+ void init() override;
+
+ void buildStiffnessMatrix(sofa::core::behavior::StiffnessMatrix* matrix) override;
+
+ using Inherit1::getPotentialEnergy;
+ SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const DataVecCoord& x) const override;
+
+ using Inherit1::addKToMatrix;
+ // almost deprecated, but here for compatibility with unit tests
+ void addKToMatrix(sofa::linearalgebra::BaseMatrix* matrix, SReal kFact, unsigned& offset) override;
+
+ sofa::SingleLink,
+ sofa::BaseLink::FLAG_STOREPATH | sofa::BaseLink::FLAG_STRONGLINK> l_material;
+
+protected:
+ using trait = sofa::component::solidmechanics::fem::elastic::trait;
+ using ElementGradient = typename trait::ElementGradient;
+
+ void validateMaterial();
+
+ bool m_isHessianValid;
+
+ void computeHessian(const VecCoord& coordinates);
+
+ /**
+ * List of precomputed element stiffness matrices
+ */
+ sofa::type::vector m_elementStiffness;
+
+ const VecCoord* m_coordinates{ nullptr };
+
+ DeformationGradient computeDeformationGradient(
+ const sofa::type::Mat& J_q,
+ const sofa::type::Mat& J_Q_inv);
+
+ struct PrecomputedData
+ {
+ // jacobian of the mapping from the reference space to the rest physical space, evaluated at the
+ // quadrature point
+ sofa::type::Mat jacobian { sofa::type::NOINIT };
+
+ // inverse of the jacobian of the mapping from the reference space to the rest physical space,
+ // evaluated at the quadrature point
+ sofa::type::Mat jacobianInv { sofa::type::NOINIT };
+
+ Real detJacobian {};
+
+ // gradient of the shape functions in the physical element evaluated at the quadrature point
+ sofa::type::Mat dN_dQ { sofa::type::NOINIT };
+ };
+
+ /**
+ * Data can be precomputed from the rest configuration and used later in computations for the
+ * current configuration. A piece of precomputed data is stored for each quadrature point in
+ * each element.
+ */
+ sofa::type::vector> m_precomputedData;
+
+ void precomputeData();
+
+ void beforeElementForce(const sofa::core::MechanicalParams* mparams,
+ sofa::type::vector& f,
+ const sofa::VecCoord_t& x) override;
+
+ void computeElementsForces(
+ const sofa::simulation::Range& range,
+ const sofa::core::MechanicalParams* mparams,
+ sofa::type::vector& f,
+ const sofa::VecCoord_t& x) override;
+
+ void beforeElementForceDeriv(const sofa::core::MechanicalParams* mparams) override;
+
+ void computeElementsForcesDeriv(
+ const sofa::simulation::Range& range,
+ const sofa::core::MechanicalParams* mparams,
+ sofa::type::vector& df,
+ const sofa::VecDeriv_t& dx) override;
+};
+
+#if !defined(ELASTICITY_COMPONENT_HYPERLASTICITY_FEM_FORCE_FIELD_CPP)
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API HyperelasticityFEMForceField;
+#endif
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.inl
new file mode 100644
index 00000000000..58a4fc1e627
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/HyperelasticityFEMForceField.inl
@@ -0,0 +1,406 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+void HyperelasticityFEMForceField::init()
+{
+ sofa::component::solidmechanics::fem::elastic::FEMForceField::init();
+
+ if (!this->isComponentStateInvalid())
+ {
+ this->validateMaterial();
+ }
+
+ if (!this->isComponentStateInvalid())
+ {
+ precomputeData();
+ }
+
+ if (!this->isComponentStateInvalid())
+ {
+ this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Valid);
+ }
+}
+
+template
+void HyperelasticityFEMForceField::buildStiffnessMatrix(
+ sofa::core::behavior::StiffnessMatrix* matrix)
+{
+ if (this->isComponentStateInvalid())
+ return;
+
+ auto dfdx = matrix->getForceDerivativeIn(this->mstate)
+ .withRespectToPositionsIn(this->mstate);
+
+ if (!m_isHessianValid)
+ {
+ computeHessian(*m_coordinates);
+ }
+
+ sofa::type::Mat localMatrix(sofa::type::NOINIT);
+
+ const auto& elements = FiniteElement::getElementSequence(*this->l_topology);
+ auto elementStiffnessIt = m_elementStiffness.begin();
+ for (const auto& element : elements)
+ {
+ const auto& stiffnessMatrix = *elementStiffnessIt++;
+
+ for (sofa::Index n1 = 0; n1 < NumberOfNodesInElement; ++n1)
+ {
+ for (sofa::Index n2 = 0; n2 < NumberOfNodesInElement; ++n2)
+ {
+ stiffnessMatrix.getsub(spatial_dimensions * n1, spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2
+ dfdx(element[n1] * spatial_dimensions, element[n2] * spatial_dimensions) += -localMatrix;
+ }
+ }
+ }
+}
+
+template
+SReal HyperelasticityFEMForceField::getPotentialEnergy(
+ const sofa::core::MechanicalParams*, const DataVecCoord& x) const
+{
+ return 0;
+}
+
+template
+void HyperelasticityFEMForceField::addKToMatrix(
+ sofa::linearalgebra::BaseMatrix* matrix, SReal kFact, unsigned& offset)
+{
+ if (this->isComponentStateInvalid())
+ return;
+
+ if (!m_isHessianValid)
+ {
+ computeHessian(*m_coordinates);
+ }
+
+ using LocalMatType = sofa::type::Mat;
+ LocalMatType localMatrix{sofa::type::NOINIT};
+
+ const auto& elements = FiniteElement::getElementSequence(*this->l_topology);
+ auto elementStiffnessIt = m_elementStiffness.begin();
+ for (const auto& element : elements)
+ {
+ const auto& stiffnessMatrix = *elementStiffnessIt++;
+
+ for (sofa::Index n1 = 0; n1 < NumberOfNodesInElement; ++n1)
+ {
+ for (sofa::Index n2 = 0; n2 < NumberOfNodesInElement; ++n2)
+ {
+ stiffnessMatrix.getsub(spatial_dimensions * n1, spatial_dimensions * n2, localMatrix); //extract the submatrix corresponding to the coupling of nodes n1 and n2
+ const auto value = (-static_cast(kFact)) * static_cast>(localMatrix);
+ matrix->add(
+ offset + element[n1] * spatial_dimensions,
+ offset + element[n2] * spatial_dimensions, value);
+ }
+ }
+ }
+}
+
+template
+void HyperelasticityFEMForceField::validateMaterial()
+{
+ if (l_material.empty())
+ {
+ msg_info() << "Link to a valid material should be set to ensure right behavior. First "
+ "material found in current context will be used.";
+ l_material.set(this->getContext()->template get>());
+ }
+
+ if (l_material == nullptr)
+ {
+ msg_error() << "No material component found at path: '" << this->l_material.getLinkedPath()
+ << "', nor in current context: " << this->getContext()->name
+ << ". Object must have a material. "
+ << "The list of available material components is: "
+ << sofa::core::ObjectFactory::getInstance()
+ ->listClassesDerivedFrom>();
+ this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
+ }
+}
+
+template
+void HyperelasticityFEMForceField::computeHessian(const VecCoord& coordinates)
+{
+ if (this->l_topology == nullptr) return;
+ if (l_material == nullptr) return;
+
+ SCOPED_TIMER("ComputeHessian");
+
+ const auto& elements = FiniteElement::getElementSequence(*this->l_topology);
+
+ if (m_precomputedData.size() != elements.size())
+ {
+ precomputeData();
+ }
+
+ m_elementStiffness.clear();
+ m_elementStiffness.resize(elements.size());
+
+ auto elementStiffnessIt = m_elementStiffness.begin();
+
+ std::size_t elementIndex = 0;
+ for (const auto& element : elements)
+ {
+ SCOPED_TIMER_TR("Element");
+ const std::array elementNodesCoordinates = sofa::component::solidmechanics::fem::elastic::extractNodesVectorFromGlobalVector(element, this->mstate->readPositions().ref());
+
+ ElementStiffness& K = *elementStiffnessIt++;
+ K.clear();
+
+ static constexpr auto quadraturePoints = FiniteElement::quadraturePoints();
+ static constexpr auto gradients = sofa::fem::FiniteElementHelper::gradientShapeFunctionAtQuadraturePoints();
+
+ for (sofa::Size q = 0; q < NumberOfQuadraturePoints; ++q)
+ {
+ const auto& weight = quadraturePoints[q].second;
+ const PrecomputedData& precomputedData = m_precomputedData[elementIndex][q];
+
+ // gradient of shape functions in the reference element evaluated at the quadrature point
+ const sofa::type::Mat& dN_dq_ref = gradients[q];
+
+ // jacobian of the mapping from the reference space to the physical space, evaluated at the
+ // quadrature point
+ const auto J_q = sofa::fem::FiniteElementHelper::jacobianFromReferenceToPhysical(elementNodesCoordinates, dN_dq_ref);
+
+ const auto detJ_Q = precomputedData.detJacobian;
+
+ const sofa::type::Mat& J_Q_inv = precomputedData.jacobianInv;
+
+ // gradient of the shape functions in the physical element evaluated at the quadrature point
+ const sofa::type::Mat& dN_dQ = precomputedData.dN_dQ;
+
+ const DeformationGradient F = computeDeformationGradient(J_q, J_Q_inv);
+
+ Strain strain(deformationGradient, F);
+
+ // derivative of first Piola-Kirchhoff stress tensor with respect to deformation gradient
+ const auto dPdF = [&]()
+ {
+ SCOPED_TIMER_VARNAME_TR(dPdFTimer, "dPdF");
+ return l_material->materialTangentModulus(strain);
+ }();
+
+ const auto factor = detJ_Q * weight;
+
+ SCOPED_TIMER_VARNAME_TR(tensorTimer, "Tensor");
+ for (sofa::Size element_i = 0; element_i < NumberOfNodesInElement; ++element_i)
+ {
+ for (sofa::Size element_j = 0; element_j < NumberOfNodesInElement; ++element_j)
+ {
+ for (sofa::Size dimension_i = 0; dimension_i < spatial_dimensions; ++dimension_i)
+ {
+ for (sofa::Size dimension_j = 0; dimension_j < spatial_dimensions; ++dimension_j)
+ {
+ auto& k = K(element_i * spatial_dimensions + dimension_i, element_j * spatial_dimensions + dimension_j);
+ for (sofa::Size i = 0; i < spatial_dimensions; ++i)
+ {
+ for (sofa::Size j = 0; j < spatial_dimensions; ++j)
+ {
+ k += factor * dN_dQ[element_i][i] * dPdF(dimension_i, i, dimension_j, j) * dN_dQ[element_j][j];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ++elementIndex;
+ }
+
+ m_isHessianValid = true;
+}
+
+template
+auto HyperelasticityFEMForceField::computeDeformationGradient(
+ const sofa::type::Mat& J_q,
+ const sofa::type::Mat& J_Q_inv) -> DeformationGradient
+{
+ return J_q * J_Q_inv;
+}
+
+template
+void HyperelasticityFEMForceField::precomputeData()
+{
+ if (this->l_topology == nullptr) return;
+
+ auto restPositionAccessor = this->mstate->readRestPositions();
+ const auto& restPosition = restPositionAccessor.ref();
+
+ const auto& elements = FiniteElement::getElementSequence(*this->l_topology);
+ m_precomputedData.resize(elements.size());
+
+ static constexpr auto gradients = sofa::fem::FiniteElementHelper::gradientShapeFunctionAtQuadraturePoints();
+
+ for (std::size_t i = 0; i < elements.size(); ++i)
+ {
+ const auto& element = elements[i];
+ const std::array elementNodesRestCoordinates = sofa::component::solidmechanics::fem::elastic::extractNodesVectorFromGlobalVector(element, restPosition);
+
+ for (std::size_t j = 0; j < NumberOfQuadraturePoints; ++j)
+ {
+ // gradient of shape functions in the reference element evaluated at the quadrature point
+ const sofa::type::Mat& dN_dq_ref = gradients[j];
+
+ PrecomputedData& data = m_precomputedData[i][j];
+ data.jacobian = sofa::fem::FiniteElementHelper::jacobianFromReferenceToPhysical(elementNodesRestCoordinates, dN_dq_ref);
+ data.jacobianInv = sofa::type::inverse(data.jacobian);
+ data.detJacobian = sofa::type::absGeneralizedDeterminant(data.jacobian);
+
+ for (sofa::Size n = 0; n < NumberOfNodesInElement; ++n)
+ {
+ data.dN_dQ[n] = data.jacobianInv.multTranspose(dN_dq_ref[n]);
+ }
+ }
+ }
+}
+template
+void HyperelasticityFEMForceField::beforeElementForce(
+ const sofa::core::MechanicalParams* mparams, sofa::type::vector& f,
+ const sofa::VecCoord_t& x)
+{
+ //store coordinates to use it later when computing the Hessian
+ m_coordinates = &x;
+
+ const auto& elements = FiniteElement::getElementSequence(*this->l_topology);
+ if (m_precomputedData.size() != elements.size())
+ {
+ precomputeData();
+ }
+
+ m_isHessianValid = false;
+
+ //reset force vector
+ for (auto& elF : f)
+ {
+ elF.clear();
+ }
+}
+
+template
+void HyperelasticityFEMForceField::computeElementsForces(
+ const sofa::simulation::Range& range, const sofa::core::MechanicalParams* mparams,
+ sofa::type::vector& f, const sofa::VecCoord_t& x)
+{
+ const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
+
+ static constexpr auto quadraturePoints = FiniteElement::quadraturePoints();
+ static constexpr auto gradients = sofa::fem::FiniteElementHelper::gradientShapeFunctionAtQuadraturePoints();
+
+ for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
+ {
+ const auto element = elements[elementId];
+ const std::array elementNodesCoordinates = sofa::component::solidmechanics::fem::elastic::extractNodesVectorFromGlobalVector(element, x);
+
+ //access to the force vector in the element. This is the value to compute in this iteration
+ //force assembly at the DoF level is done in a later function.
+ auto& elementForce = f[elementId];
+
+ for (sofa::Size q = 0; q < NumberOfQuadraturePoints; ++q)
+ {
+ const auto& weight = quadraturePoints[q].second;
+ const PrecomputedData& precomputedData = m_precomputedData[elementId][q];
+
+ // gradient of shape functions in the reference element evaluated at the quadrature point
+ const sofa::type::Mat& dN_dq_ref = gradients[q];
+
+ // jacobian of the mapping from the reference space to the physical space, evaluated at the
+ // quadrature point
+ const auto J_q = sofa::fem::FiniteElementHelper::jacobianFromReferenceToPhysical(elementNodesCoordinates, dN_dq_ref);
+
+ const auto detJ_Q = precomputedData.detJacobian;
+
+ const sofa::type::Mat& J_Q_inv = precomputedData.jacobianInv;
+
+ // gradient of the shape functions in the physical element evaluated at the quadrature point
+ const sofa::type::Mat& dN_dQ = precomputedData.dN_dQ;
+
+ const DeformationGradient F = computeDeformationGradient(J_q, J_Q_inv);
+
+ Strain strain(deformationGradient, F);
+ const auto P = l_material->firstPiolaKirchhoffStress(strain);
+
+ for (sofa::Size i = 0; i < trait::NumberOfNodesInElement; ++i)
+ {
+ const auto f_q = (detJ_Q * weight) * P * dN_dQ[i];
+ for (sofa::Size j = 0; j < trait::spatial_dimensions; ++j)
+ {
+ elementForce[i * trait::spatial_dimensions + j] += f_q[j];
+ }
+ }
+ }
+ }
+}
+
+template
+void HyperelasticityFEMForceField::beforeElementForceDeriv(
+ const sofa::core::MechanicalParams* mparams)
+{
+ if (!m_isHessianValid)
+ {
+ computeHessian(*m_coordinates);
+ }
+}
+
+template
+void HyperelasticityFEMForceField::computeElementsForcesDeriv(
+ const sofa::simulation::Range& range, const sofa::core::MechanicalParams* mparams,
+ sofa::type::vector& df, const sofa::VecDeriv_t& dx)
+{
+ const auto& elements = trait::FiniteElement::getElementSequence(*this->l_topology);
+
+ for (std::size_t elementId = range.start; elementId < range.end; ++elementId)
+ {
+ const auto& element = elements[elementId];
+ const auto& stiffnessMatrix = m_elementStiffness[elementId];
+
+ const std::array, trait::NumberOfNodesInElement> elementNodesDx =
+ sofa::component::solidmechanics::fem::elastic::extractNodesVectorFromGlobalVector(element, dx);
+
+ sofa::type::Vec> element_dx(sofa::type::NOINIT);
+ for (sofa::Size nodeId = 0; nodeId < trait::NumberOfNodesInElement; ++nodeId)
+ {
+ const auto& nodeDx = elementNodesDx[nodeId];
+ for (sofa::Size dim = 0; dim < trait::spatial_dimensions; ++dim)
+ {
+ element_dx[nodeId * trait::spatial_dimensions + dim] = nodeDx[dim];
+ }
+ }
+
+ df[elementId] = stiffnessMatrix * element_dx;
+ }
+}
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.cpp b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.cpp
new file mode 100644
index 00000000000..3b6b715d009
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.cpp
@@ -0,0 +1,32 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#define ELASTICITY_COMPONENT_PK2HYPERELASTIC_MATERIAL_CPP
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.h
new file mode 100644
index 00000000000..f404918752e
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+/**
+ * A hyperelastic material defined by its second Piola-Kirchhoff stress tensor and its Lagrangian
+ * elasticity tensor.
+ */
+template
+class PK2HyperelasticMaterial : public HyperelasticMaterial
+{
+public:
+ SOFA_CLASS(PK2HyperelasticMaterial, HyperelasticMaterial);
+ using DataTypes = TDataTypes;
+
+protected:
+ using DeformationGradient = typename HyperelasticMaterial::DeformationGradient;
+ using RightCauchyGreenTensor = typename HyperelasticMaterial::RightCauchyGreenTensor;
+ using StressTensor = typename HyperelasticMaterial::StressTensor;
+ using ElasticityTensor = typename HyperelasticMaterial::ElasticityTensor;
+ using TangentModulus = typename HyperelasticMaterial::TangentModulus;
+ using HyperelasticMaterial::spatial_dimensions;
+
+public:
+ StressTensor firstPiolaKirchhoffStress(Strain& strain) final;
+ TangentModulus materialTangentModulus(Strain& strain) final;
+
+protected:
+ virtual StressTensor secondPiolaKirchhoffStress(Strain& strain) = 0;
+ virtual ElasticityTensor elasticityTensor(Strain& strain) = 0;
+};
+
+#if !defined(ELASTICITY_COMPONENT_HYPERELASTIC_MATERIAL_CPP)
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API PK2HyperelasticMaterial;
+#endif
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.inl
new file mode 100644
index 00000000000..eaa7790cd3a
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/PK2HyperelasticMaterial.inl
@@ -0,0 +1,67 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+#include
+
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+auto PK2HyperelasticMaterial::firstPiolaKirchhoffStress(Strain& strain) -> StressTensor
+{
+ const auto& F = strain.deformationGradient();
+ const auto S = secondPiolaKirchhoffStress(strain);
+ return F * S;
+}
+
+template
+auto PK2HyperelasticMaterial::materialTangentModulus(Strain& strain) -> TangentModulus
+{
+ using Real = sofa::Real_t;
+ SCOPED_TIMER_TR("tangentModulus");
+
+ const auto& F = strain.deformationGradient();
+ const auto C = elasticityTensor(strain);
+ const auto S = secondPiolaKirchhoffStress(strain);
+
+ const auto A = TangentModulus([&F, &C, &S](sofa::Index i, sofa::Index j, sofa::Index k, sofa::Index l)
+ {
+ auto A_ijkl = sofa::component::solidmechanics::fem::elastic::kroneckerDelta(i,k) * S(l, j);
+ for (std::size_t q = 0; q < spatial_dimensions; ++q)
+ {
+ for (std::size_t r = 0; r < spatial_dimensions; ++r)
+ {
+ A_ijkl += F(i, q) * C(q, j, l, r) * F(k, r);
+ }
+ }
+ return A_ijkl;
+ });
+
+ return A;
+}
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.cpp b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.cpp
new file mode 100644
index 00000000000..be2ec4c7c6e
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.cpp
@@ -0,0 +1,44 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#define ELASTICITY_COMPONENT_MATERIAL_INCOMPRESSIBLEMOONEYRIVLIN_CPP
+
+#include
+#include
+
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+void registerIncompressibleMooneyRivlinMaterial(sofa::core::ObjectFactory* factory)
+{
+ factory->registerObjects(sofa::core::ObjectRegistrationData("Incompressible Mooney-Rivlin material")
+ .add< IncompressibleMooneyRivlinMaterial >()
+ .add< IncompressibleMooneyRivlinMaterial >()
+ .add< IncompressibleMooneyRivlinMaterial >(true));
+}
+
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.h
new file mode 100644
index 00000000000..097051d85ba
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+
+#if !defined(ELASTICITY_COMPONENT_MATERIAL_INCOMPRESSIBLEMOONEYRIVLIN_CPP)
+#include
+#endif
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+class IncompressibleMooneyRivlinMaterial :
+ public PK2HyperelasticMaterial
+{
+public:
+ SOFA_CLASS(IncompressibleMooneyRivlinMaterial, PK2HyperelasticMaterial);
+
+private:
+ using Real = sofa::Real_t;
+
+ static constexpr sofa::Size spatial_dimensions = DataTypes::spatial_dimensions;
+
+ using DeformationGradient = typename PK2HyperelasticMaterial::DeformationGradient;
+ using RightCauchyGreenTensor = typename PK2HyperelasticMaterial::RightCauchyGreenTensor;
+ using StressTensor = typename PK2HyperelasticMaterial::StressTensor;
+ using ElasticityTensor = typename PK2HyperelasticMaterial::ElasticityTensor;
+
+public:
+ sofa::Data m_mu10;
+ sofa::Data m_mu01;
+
+ StressTensor secondPiolaKirchhoffStress(Strain& strain) override;
+
+ ElasticityTensor elasticityTensor(Strain& strain) override;
+
+protected:
+ IncompressibleMooneyRivlinMaterial();
+};
+
+
+#if !defined(ELASTICITY_COMPONENT_MATERIAL_INCOMPRESSIBLEMOONEYRIVLIN_CPP)
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API IncompressibleMooneyRivlinMaterial;
+#endif
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.inl
new file mode 100644
index 00000000000..59a884b3cdb
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/IncompressibleMooneyRivlinMaterial.inl
@@ -0,0 +1,68 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+IncompressibleMooneyRivlinMaterial::IncompressibleMooneyRivlinMaterial()
+ : m_mu10(initData(&m_mu10, static_cast(1e3), "mu10",
+ "Material constant associated to the first invariant"))
+ , m_mu01(initData(&m_mu01, static_cast(1e3), "mu01",
+ "Material constant associated to the second invariant"))
+{}
+
+template
+auto IncompressibleMooneyRivlinMaterial::secondPiolaKirchhoffStress(Strain& strain) -> StressTensor
+{
+ static constexpr auto& I = Strain::identity;
+ const auto& C = strain.getRightCauchyGreenTensor();
+
+ const auto invariant1 = strain.getInvariant1();
+
+ const auto mu10 = m_mu10.getValue();
+ const auto mu01 = m_mu01.getValue();
+
+ return static_cast(2) * mu10 * I + static_cast(2) * mu01 * (invariant1 * I - C);
+}
+
+template
+auto IncompressibleMooneyRivlinMaterial::elasticityTensor(Strain& strain) -> ElasticityTensor
+{
+ auto delta = [](auto i, auto j){ return sofa::component::solidmechanics::fem::elastic::kroneckerDelta(i, j); };
+
+ return ElasticityTensor(
+ [mu01 = m_mu01.getValue(), &delta](sofa::Index i, sofa::Index j, sofa::Index k, sofa::Index l)
+ {
+ return 2 * mu01 * (
+ 2 * delta(i, j) * delta(k, l)
+ - delta(i, k) * delta(j, l)
+ - delta(i, l) * delta(j, k)
+ );
+ });
+}
+
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.cpp b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.cpp
new file mode 100644
index 00000000000..83d947706c1
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.cpp
@@ -0,0 +1,32 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#define ELASTICITY_COMPONENT_LINEAR_MECHANICAL_PARAMETERS_CPP
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+
+}
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.h
new file mode 100644
index 00000000000..68ee4eb8ee0
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+
+#include
+#include
+
+#if !defined(ELASTICITY_COMPONENT_LINEAR_MECHANICAL_PARAMETERS_CPP)
+#include
+#endif
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+class LinearMechanicalParametersComponent : public virtual sofa::core::objectmodel::BaseObject
+{
+ using Real = sofa::Real_t;
+
+public:
+ SOFA_CLASS(LinearMechanicalParametersComponent, sofa::core::objectmodel::BaseObject);
+
+ sofa::Data d_poissonRatio;
+ sofa::Data d_youngModulus;
+
+protected:
+ LinearMechanicalParametersComponent();
+
+ void setLameCoefficients();
+
+ // Lamé's coefficients
+ Real m_lambda, m_mu;
+};
+
+#if !defined(ELASTICITY_COMPONENT_LINEAR_MECHANICAL_PARAMETERS_CPP)
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API LinearMechanicalParametersComponent;
+#endif
+} // namespace elasticity
diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.inl
new file mode 100644
index 00000000000..e28697f9ef1
--- /dev/null
+++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/hyperelasticmaterials/LinearMechanicalParametersComponent.inl
@@ -0,0 +1,60 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+#include
+
+namespace sofa::component::solidmechanics::fem::hyperelastic
+{
+
+template
+LinearMechanicalParametersComponent::LinearMechanicalParametersComponent()
+: d_poissonRatio(initData(&d_poissonRatio, static_cast