Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
98 lines (70 sloc) 4.7 KB


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

State vectors

The MechanicalState saves all the state vectors, namely the degrees of freedom (DOFs), their associated velocity, acceleration and the forces applied on the simulated body. By gathering all state vectors, the MechanicalObject avoids multiple calls of virtual functions. 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 was historically focused on soft tissue mechanics. Therefore, the semantic is strongly related to mechanics. In the MechanicalObject, 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.

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

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, e.g.:

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:

class TStandardVec
    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
class TStandardVec
    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


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).
  • Rigid: this DataType corresponds to 7 DOFs per node, this can be used to simulate rigid bodies (3 positions and 1 quaternion).


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

<Node name="root" dt="0.01" gravity="0 -9.81 0">
    <DefaultAnimationLoop />
    <MechanicalObject template="Vec3f" name="myDOFs" />

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 agressive compiler optimizations. Nodes with different DOFs must be stored in two different MechanicalObjects.

You can’t perform that action at this time.