Skip to content

[FEM.Elastic] Introduce generic element-agnostic elastic FEM force field#5882

Open
alxbilger wants to merge 16 commits intosofa-framework:masterfrom
alxbilger:elasticity
Open

[FEM.Elastic] Introduce generic element-agnostic elastic FEM force field#5882
alxbilger wants to merge 16 commits intosofa-framework:masterfrom
alxbilger:elasticity

Conversation

@alxbilger
Copy link
Contributor

@alxbilger alxbilger commented Jan 22, 2026

Coming from https://github.com/alxbilger/Elasticity

TODO:

  • add tests
  • add scenes

By submitting this pull request, I acknowledge that
I have read, understand, and agree SOFA Developer Certificate of Origin (DCO).


Reviewers will merge this pull-request only if

  • it builds with SUCCESS for all platforms on the CI.
  • it does not generate new warnings.
  • it does not generate new unit test failures.
  • it does not generate new scene test failures.
  • it does not break API compatibility.
  • it is more than 1 week old (or has fast-merge label).

@alxbilger alxbilger added pr: status to review To notify reviewers to review this pull-request pr: new feature Implement a new feature pr: highlighted in next release Highlight this contribution in the notes of the upcoming release labels Jan 22, 2026
@hugtalbot hugtalbot added the topic for next dev-meeting PR to be discussed in sofa-dev meeting label Jan 23, 2026
@fredroy
Copy link
Contributor

fredroy commented Jan 28, 2026

[ci-build][with-all-tests]

Copy link
Contributor

@th-skam th-skam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only touched some easy to read files. Will try to take a better look in the next days.
But I really like the overall work.

@alxbilger alxbilger removed the topic for next dev-meeting PR to be discussed in sofa-dev meeting label Feb 5, 2026
@hugtalbot
Copy link
Contributor

This PR deserves the attention of all @sofa-framework/reviewers

for (sofa::Size l = 0; l < spatial_dimensions; ++l)
{
const auto ijkl = callable(i, j, k, l);
const auto jikl = callable(i, j, k, l);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const auto jikl = callable(i, j, k, l);
const auto jikl = callable(j, i, k, l);

return gradient;
}

static constexpr std::array<QuadraturePointAndWeight, 4> quadraturePoints()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we be using 8-point rule for hexas? And similarly 4-point rule for quads instead of 3 in the respective file?
I guess it's a performance/approximative trade-off but if the work coming from Elasticity is to be used for didacticism, perhaps we should have some comment here and mention that it is approximative.

* @param youngModulus The Young's modulus of the material, representing its stiffness.
* @param poissonRatio The Poisson's ratio of the material, describing its deformation behavior.
* @return The isotropic elasticity tensor represented as an object of
* `ElasticityTensor<DataTypes>`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `ElasticityTensor<DataTypes>`.
* `FullySymmetric4Tensor<DataTypes>`.

Comment on lines +168 to +177
auto row = spatial_dimensions;
for (sofa::Size i = 0; i < spatial_dimensions; ++i)
{
for (sofa::Size j = i + 1; j < spatial_dimensions; ++j)
{
B(row, ne * spatial_dimensions + i) = gradientShapeFunctions[ne][j];
B(row, ne * spatial_dimensions + j) = gradientShapeFunctions[ne][i];
++row;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto row = spatial_dimensions;
for (sofa::Size i = 0; i < spatial_dimensions; ++i)
{
for (sofa::Size j = i + 1; j < spatial_dimensions; ++j)
{
B(row, ne * spatial_dimensions + i) = gradientShapeFunctions[ne][j];
B(row, ne * spatial_dimensions + j) = gradientShapeFunctions[ne][i];
++row;
}
}
for (sofa::Size i = 0; i < spatial_dimensions; ++i)
{
for (sofa::Size j = i + 1; j < spatial_dimensions; ++j)
{
const auto row = tensorToVoigtIndex<DataTypes>(i, j);
B(row, ne * spatial_dimensions + i) = gradientShapeFunctions[ne][j];
B(row, ne * spatial_dimensions + j) = gradientShapeFunctions[ne][i];
}
}

There's a mismatch here between what's in VoigtNotation.h which states:
For 3D: (0,0)->0, (1,1)->1, (2,2)->2, (1,2)->3, (0,2)->4, (0,1)->5

But if you unroll the loop here, you would get
row = 3 -> (0,1), 4 -> (0,2), 5 -> (1,2) so 3 and 5 from voigt are swapped.

So the B^T C B in ElementStiffnessMatrix.h mixes them up.
And I assume we're getting away with it because we're dealing with isotropic problems but if the same code is to be used in the future we won't. Better to have a test to verify this now.


const auto H = P.multTranspose(Q);

sofa::helper::Decompose<sofa::Real_t<DataTypes>>::polarDecomposition_stable(H, rotationMatrix);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the diff with the regular one ? Why keep both ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea. As usual, I want to keep compatibility with legacy SOFA. TetrahedronFEMForceField offers the option to select both polar decomposition. SVD uses the stable polar decomposition.

Comment on lines +117 to +118
const auto klij = callable(k, l, i, j);
const auto ijlk = callable(i, j, l, k);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the second minor symetry missing ? That being said, testing the first one and the major one seems sufficient.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be purely added to the Core Matrix API

@hugtalbot
Copy link
Contributor

I insist on the fact that this PR deserves the attention of all @sofa-framework/reviewers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: highlighted in next release Highlight this contribution in the notes of the upcoming release pr: new feature Implement a new feature pr: status to review To notify reviewers to review this pull-request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants