Skip to content

[Mapping.Linear] Add applyJT for matrices for IdentityMultiMapping#6033

Open
alxbilger wants to merge 2 commits intosofa-framework:masterfrom
alxbilger:applyjtmultimapping
Open

[Mapping.Linear] Add applyJT for matrices for IdentityMultiMapping#6033
alxbilger wants to merge 2 commits intosofa-framework:masterfrom
alxbilger:applyjtmultimapping

Conversation

@alxbilger
Copy link
Contributor

Based on #6032

The goal was to verify that the two following scenes produce the same behaviour:

  1. Two objects in the same solver. No mapping involved
<Node name="root" gravity="0 -9.81 0">

    <Node name="meshes">
        <StringMeshCreator name="string_1" resolution="10"/>
        <StringMeshCreator name="string_2" resolution="8"/>
    </Node>

    <EulerImplicitSolver/>
    <SparseLDLSolver template="CompressedRowSparseMatrixMat3x3d"/>
    <GlobalSystemMatrixImage/>

    <Node name="string_1">
        <MechanicalObject name="state" src="@/meshes/string_1" translation="0 0 0.5" />
        <MeshTopology src="@/meshes/string_1" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
        <UniformMass vertexMass="2"/>
    </Node>

    <Node name="string_2">
        <MechanicalObject name="state" src="@/meshes/string_2" translation="0 0 -0.5" />
        <MeshTopology src="@/meshes/string_2" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
        <UniformMass vertexMass="2"/>
    </Node>
</Node>
  1. Two objects. The mass is mapped, applied on the concatenation of both objects.
<Node name="root" gravity="0 -9.81 0">

    <Node name="meshes">
        <StringMeshCreator name="string_1" resolution="10"/>
        <StringMeshCreator name="string_2" resolution="8"/>
    </Node>

    <EulerImplicitSolver/>
    <SparseLDLSolver template="CompressedRowSparseMatrixMat3x3d"/>

    <Node name="string_1">
        <MechanicalObject name="state" src="@/meshes/string_1" translation="0 0 0.5" />
        <MeshTopology src="@/meshes/string_1" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
    </Node>

    <Node name="string_2">
        <MechanicalObject name="state" src="@/meshes/string_2" translation="0 0 -0.5" />
        <MeshTopology src="@/meshes/string_2" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
    </Node>

    <Node name="mass">
        <MechanicalObject name="state"/>
        <IdentityMultiMapping input="@../string_1/state @../string_2/state" output="@state"/>
        <UniformMass vertexMass="2"/>
    </Node>
</Node>

Both scene should produce the same result. Except that the scene with the mapping has a problem. See the system matrix:

missingMass

The mass matrix is missing. It's because IdentityMultiMapping does not implement applyJT for matrices.

With this PR, the system matrices is now:
afterPR

Note:
IdentityMultiMapping is not available in <Vec3,Vec2>, but I made sure that the current implementation is compatible with such templates. For example, I tried the following scene:

<Node name="root" gravity="0 -9.81 0">

    <Node name="meshes">
        <StringMeshCreator name="string_1" resolution="10"/>
        <StringMeshCreator name="string_2" resolution="8"/>
    </Node>

    <EulerImplicitSolver/>
    <SparseLDLSolver template="CompressedRowSparseMatrixMat3x3d"/>

    <Node name="string_1">
        <MechanicalObject name="state" src="@/meshes/string_1" translation="0 0 0.5" />
        <MeshTopology src="@/meshes/string_1" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
    </Node>

    <Node name="string_2">
        <MechanicalObject name="state" src="@/meshes/string_2" translation="0 0 -0.5" />
        <MeshTopology src="@/meshes/string_2" />
        <MeshSpringForceField name="spring" drawMode="1" linesStiffness="1000"/>
        <FixedProjectiveConstraint indices="0"/>
    </Node>

    <Node name="mass">
        <MechanicalObject name="state" template="Vec2"/>   <!-- Note here the 2d -->
        <IdentityMultiMapping input="@../string_1/state @../string_2/state" output="@state"/> <!-- not available, but I compiled it for the experiment -->
        <UniformMass vertexMass="2"/>
    </Node>
</Node>

The system matrix is:
afterPR_2d

It is rank-deficient, but it is expected (the mass is computed in 2d, not in 3d. One component is missing). So it works as expected.


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: enhancement About a possible enhancement pr: status to review To notify reviewers to review this pull-request pr: based on previous PR PR based on a previous PR, therefore to be merged ONLY subsequently labels Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: based on previous PR PR based on a previous PR, therefore to be merged ONLY subsequently pr: enhancement About a possible enhancement 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.

1 participant