Skip to content

MechanicalObject

The main component of a simulation in SOFA is the MechanicalObject. It inherits from MechanicalState, itself inheriting from State.

State vectors

The MechanicalObject (MechanicalState) saves all the state vectors. These state vectors correspond to the degrees of freedom (DOFs) and their first time derivative. The vector size is the number of nodes, and the size of each vector entry depends on the template (see below).

Note: the SOFA framework being historically focused on soft tissue mechanics, the semantic is strongly related to mechanics. The state vectors (DOFs) are stored in the field named position, their first derivatives in the velocity field and their second derivatives in the acceleration field.

Templates

The state vectors can contain different type of data depending on the degrees of freedom (DOFs). In order to provide generic implementation, components (C++ classes) in SOFA will be templated on DataTypes.

SOFA supports several DataTypes corresponding to the DOFs:

  • Vec1f or Vec1d: 1 DOF per node is used. For instance, this can be used for thermodynamics (temperature field). Vec1f denotes vectors of float and Vec1d denotes the use of doubles.
  • Vec2f or Vec2d: 2 DOFs per node are used. For instance, this can be used for cardiac electrophysiology.
  • Vec3f or Vec3d: 3 DOFs per node are used. For instance, this can be used for mechanics.
  • Vec6f or Vec6d: 6 DOFs per node are used. For instance, this can be used for beam simulations (3 translations and 3 rotations).
  • Rigid3d: this DataType corresponds to 7 DOFs per node, this can be used to simulate rigid bodies (3 positions and 1 quaternion).

In the MechanicalObject, each of these state vectors can be accessed using (scattered) state vectors, called multi-vectors or MultiVec.

List of state vectors (MultiVec)

Vector name
Vector type Description
State position VecCoord current coordinates of the degrees of freedom
velocity VecDeriv current first derivative in time of the coordinates of the degrees of freedom
derivX VecDeriv x vector of the linear system Ax=b (therefore depends on the integration scheme)
reset_position VecCoord coordinates of the degrees of freedom used for reset
reset_velocity VecDeriv first derivative in time of the coordinates of the degrees of freedom used for reset
Force force VecDeriv b vector of the linear system Ax=b (therefore depends on the integration scheme)
externalForce VecDeriv vector containing only forces resulting from InteractionForceFields and some constraint forces
dforce VecDeriv vector corresponding to the derivative of the forces (no much use in the code base)
Rest State rest_position VecCoord coordinates of the degrees of freedom when the object is at rest (no force acting)
FreeMotion free_position VecCoord in the FreeMotionAnimationLoop, coordinates of the degrees of freedom as if no collision would be taken into account (free motion)
free_velocity VecDeriv in the FreeMotionAnimationLoop, first derivative in time of the coordinates of the degrees of freedom as if no collision would be taken into account (free motion)
Jacobian constraint MatrixDeriv matrix containing the constraint directions, i.e. derivative of the constraint laws
mappingJacobian MatrixDeriv matrix accumulating the Jacobian matrices of mappings, used only in the MechanicalMatrixMapper

Symbolic ids

The MultiVec entries are not directly accessible by the solvers. The MultiVec are represented by identificators. The operations on the vectors are implemented using visitors which contain the identificators of the relevant vectors. The MultiVec identificators (MultiVecId) have different types, depending on the data they contain (positions or their derivatives) and the access mode.

The use of symbolic identificators (MultiVecId) prevent other components (like solvers) from handling state vectors directly and allow to easily work with abstract MultiVec by using their ids. These symbolic ids are widely used by specialized visitors, like the ones used in ODESolver.

typedef TMultiVecId<V_COORD, V_READ>  ConstMultiVecCoordId;
typedef TMultiVecId<V_COORD, V_WRITE>      MultiVecCoordId;
typedef TMultiVecId<V_DERIV, V_READ>  ConstMultiVecDerivId;
typedef TMultiVecId<V_DERIV, V_WRITE>      MultiVecDerivId;

For simplicity, standard state vectors are represented using constant identificators:

template
class TStandardVec
{
public:
    typedef TVecId MyVecId;
    static MyVecId position()      { return MyVecId(1);}
    static MyVecId restPosition()  { return MyVecId(2);}
    static MyVecId freePosition()  { return MyVecId(3);}
    static MyVecId resetPosition() { return MyVecId(4);}
    enum { V_FIRST_DYNAMIC_INDEX = 5 }; ///< This is the first index used for dynamically allocated vectors

};
template
class TStandardVec
{
public:
    typedef TVecId MyVecId;
    static MyVecId velocity()       { return MyVecId(1); }
    static MyVecId resetVelocity()  { return MyVecId(2); }
    static MyVecId freeVelocity()   { return MyVecId(3); }
    static MyVecId normal()         { return MyVecId(4); }
    static MyVecId force()          { return MyVecId(5); }
    static MyVecId externalForce()  { return MyVecId(6); }
    static MyVecId dx()             { return MyVecId(7); }
    static MyVecId dforce()         { return MyVecId(8); }
    static MyVecId accFromFrame()   { return MyVecId(9); }
    enum { V_FIRST_DYNAMIC_INDEX = 11 }; ///< This is the first index used for dynamically allocated vectors
...
};

Example

In an XML format, this would be written as follows:

<Node name="root" dt="0.01" >
    <DefaultAnimationLoop />
    <MechanicalObject template="Vec3d" name="myDOFs" position="0 0 0"/>
</Node>

The C++ templates avoid code redundancy between scalar types and DOFs types. All nodes in a vector have the same type, known at compilation time to allow aggressive compiler optimizations. Nodes with different DOFs must be stored in two different MechanicalObjects.