Implement multi-cell finite element method for interpolated flexes.

This change introduces a `flex_cellcount` field to `mjModel` to specify the number of cells in each dimension for interpolated flexes. The stiffness computation, passive force calculation, and Jacobian derivatives are updated to operate on a per-cell basis, significantly improving performance by localizing computations to the nodes within each cell.

PiperOrigin-RevId: 901216393
Change-Id: Ic23132e609de11e71bb7fef8d1f139daad2ec264
This commit is contained in:
Alessio Quaglino
2026-04-17 04:10:54 -07:00
committed by Copybara-Service
parent 8415dff307
commit 6c7ed66781
36 changed files with 1777 additions and 1039 deletions
+19 -2
View File
@@ -3700,8 +3700,14 @@ saving the XML:
.. _body-flexcomp-count:
:at:`count`: :at-val:`int(3), "10 10 10"`
The number of automatically generated points in each dimension. This and the next attribute only apply to types grid,
box, cylinder, ellipsoid.
Specifies the number of automatically generated points in each dimension for types **grid**, **box**, **cylinder**,
and **ellipsoid**.
.. _body-flexcomp-cellcount:
:at:`cellcount`: :at-val:`int(3), "1 1 1"`
Specifies the number of cells in each dimension for the background interpolation grid when using **trilinear** or
**quadratic** dofs.
.. _body-flexcomp-spacing:
@@ -4242,6 +4248,17 @@ cases, the user will specify a :el:`flexcomp` which will then automatically cons
An array of MuJoCo body names (separated by white space) to which each node belongs. The number of body names
should equal the number of nodes (nnode). See the flexcomp :ref:`dof<body-flexcomp-dof>` attribute for more details.
.. _deformable-flex-cellcount:
:at:`cellcount`: :at-val:`int(3), optional`
When using **trilinear** or **quadratic** dofs, this specifies the number of cells in each dimension for the
background interpolation grid.
.. _deformable-flex-dof:
:at:`dof`: :at-val:`[trilinear, quadratic], optional`
Interpolation order for the flex.
.. _flex-edge:
:el-prefix:`flex/` |-| **edge** |?|
+9
View File
@@ -1417,6 +1417,9 @@
.. grid-item::
:ref:`count<body-flexcomp-count>`
.. grid-item::
:ref:`cellcount<body-flexcomp-cellcount>`
.. grid-item::
:ref:`spacing<body-flexcomp-spacing>`
@@ -1657,6 +1660,12 @@
.. grid-item::
:ref:`node<deformable-flex-node>`
.. grid-item::
:ref:`cellcount<deformable-flex-cellcount>`
.. grid-item::
:ref:`dof<deformable-flex-dof>`
.. dropdown:: :ref:`contact<flex-contact>` :octicon:`dot`
+9
View File
@@ -2,6 +2,15 @@
Changelog
=========
Upcoming version (not yet released)
-----------------------------------
General
^^^^^^^
- Added :ref:`multi-cell support<body-flexcomp-cellnum>` for trilinear and quadratic flexes. Note that the implicit
integrator uses a dense solver for the flex degrees of freedom, which can be slow for multi-cell flexes.
Version 3.7.0 (April 14, 2026)
------------------------------
+3
View File
@@ -1315,6 +1315,7 @@ struct mjModel_ {
int* flex_matid; // material id for rendering (nflex x 1)
int* flex_group; // group for visibility (nflex x 1)
int* flex_interp; // interpolation (0: vertex, 1: nodes) (nflex x 1)
int* flex_cellnum; // finite cell num per dimension (nflex x 3)
int* flex_nodeadr; // first node address (nflex x 1)
int* flex_nodenum; // number of nodes (nflex x 1)
int* flex_vertadr; // first vertex address (nflex x 1)
@@ -2256,6 +2257,8 @@ typedef struct mjsFlex_ { // flex specification
double damping; // Rayleigh's damping
double thickness; // thickness (2D only)
int elastic2d; // 2D passive forces; 0: none, 1: bending, 2: stretching, 3: both
int cellcount[3]; // grid cell count for finite cell method
int order; // interpolation order (1: trilinear, 2: quadratic)
// mesh properties
mjStringVec* nodebody; // node body names
+10
View File
@@ -1442,6 +1442,16 @@ instead to specify shear and volumetric stiffnesses separately using the `Poisso
<https://en.wikipedia.org/wiki/Poisson%27s_ratio>`__ of the material. For more details, see the `Saint Venant-Kirchhoff
<https://en.wikipedia.org/wiki/Hyperelastic_material#Saint_Venant%E2%80%93Kirchhoff_model>`__ hyperelastic model.
**Parametrization types**.
While the default behavior of :el:`flexcomp` produces a "full" flex where every node corresponds to a MuJoCo body, it
also supports specialized :ref:`parametrizations<body-flexcomp-dof>` for volumetric objects: **trilinear** and
**quadratic**. Instead of directly simulating all nodes, these options define a background grid of cells. The positions
of the interior vertices are computed by interpolating the positions of the cell corners. Trilinear flexes use 8-node
hexahedral cells with linear interpolation along each axis, while quadratic flexes use 27-node cells with quadratic
interpolation, allowing for curved deformation modes. These grid-based parametrizations require fewer degrees of freedom
than full flexes and can result in significantly faster simulation times, especially for large volumetric soft bodies.
**Creation and visualization**.
.. code-block:: xml