# Mappings

In SOFA, all the different representations of an object can be modeled and considered separately:

- the physical model (e.g. a mechanical behavior relying on a linear elasticity, computed on a tetrahedral topology)
- the visual model (e.g. a triangular mesh using a very high resolution)
- the collision model (e.g. a grid bounding with quad faces around our physical object)

Relying on different geometrical models, this modular approach allows to tune the computational effort set on each of these representations in order to find the best trade-off between accuracy and efficiency. However, the simulation must ensure the coherency of these different representations: for instance, we want our visual model to move according to the physics. To do so, SOFA relies on *Mappings* to ensure this corresponding between the different representations of one-or-more object (physics, visual, collision etc.)

## Matrix approach

Typical mappings compute the correspondence between different geometrical models by computing local coordinates (for rigid bodies) or barycentric coordinates (for deformable bodies). Once this correspondence is computed, it allows to project vectors (like forces) from one representation to another.

One can define two representations of an object, both using a different topology:

- one mechanical model with its degrees of freedom
- one collision model with its degrees of freedom

The mapping defines a function (that can be non-linear) mapping kinematically the position of the parent mechanical model to the child collision model: . The derivative of the degrees of freedom (velocities in case of positions) can be mapped in a similar way using the relationship , with is the associated Jacobian matrix. The mechanical model thus drives the collision model. In the case of a *BarycentricMapping*, the matrix includes the barycentric coordinates.

By applying the principle of virtual work, the mapping can also translate forces applied to the child collision model into forces applied to the parent mechanical model , using the relationship . Mappings can therefore build a bijective correspondence between two representations of an object. Note that several mappings can also be applied recursively when necessary.

When a force field is associated to a mapped state, it contributes to the stiffness matrix indirectly, through the mapping. Two terms appear.

- The first term is the projection of the mapped stiffness matrix from the mapped space into the main state .
- The second term is called geometric stiffness: . Geometric stiffness relies on the derivative of the Jacobian matrix. This derivative is null if the mapping is linear.

⚠️

WARNING: Depending on the nature of a non-linear mapping, geometric stiffness may lead to non-symmetric terms in the mechanical matrix. Such mappings have an option to make the contributions symmetric. An alternative is to use an appropriate linear solver (LU solver for example).

## API of mappings

As explained above, the mappings propagate positions, velocities, displacements and accelerations top-down, and they propagate forces bottom-up. The top-down propagation methods are:

```
//for positions
const MechanicalParams*, MultiVecCoordId outPos, ConstMultiVecCoordId inPos );
apply (
//for velocities and small displacements
const MechanicalParams*, MultiVecDerivId outVel, ConstMultiVecDerivId inVel );
applyJ(
//for accelerations, taking into account velocity-dependent accelerations in nonlinear mappings
const MechanicalParams*, MultiVecDerivId outAcc, ConstMultiVecDeri inVel, ConstMultiVecDerivId inAcc ); computeAccFromMapping(
```

The bottom-up propagation methods are:

```
//for child forces or changes of child forces
const MechanicalParams*, MultiVecDerivId inForce, ConstMultiVecDerivId outForce );
applyJT(
//for changes of parent force due to a change of mapping with constant child force
const MechanicalParams*, MultiVecDerivId parentForce, ConstMultiVecDerivId childForce );
applyDJT(
//for constraint Jacobians
const ConstraintParams*, MultiMatrixDerivId inConst, ConstMultiMatrixDerivId outConst ); applyJT(
```

## Topological mapping

Topological mappings are an additional type of mappings making the correspondence between hierarchical topologies. You can thus find :

- a
*Hexa2TetraTopologicalMapping*: computing the correspondence between a hexahedral and a tetrahedral topology, by dividing each hexahedron into 6 tetrahedra - a
*Hexa2QuadTopologicalMapping*: computing the correspondence between a hexahedral topology and its surface quadrangular topology - a
*Tetra2TriangleTopologicalMapping*: computing the correspondence between a tetrahedral topology and its surface triangular topology - a
*Quad2TriangleTopologicalMapping*: computing the correspondence between a quadrangular and a triangular topology, by dividing each quad into 2 triangles - a
*Triangle2EdgeTopologicalMapping*: computing the correspondence between a triangular and an edge topology

Last modified: 18 April 2024