PositionBasedDynamicsProjectiveConstraint
Position-based dynamics Position-based dynamics as described in [Muller06]: input: target positions X output : x(t) <- x(t) + stiffness.( X - x(t) ) v(t) <- [ x(t) - x(t-1) ] / dt = v(t) + stiffness.( X - x(t) ) /dt
The PositionBasedDynamicsProjectiveConstraint enforces position-based dynamics by blending current positions towards target positions based on a specified stiffness parameter and updating velocities accordingly.
- module
- Sofa.Component.Constraint.Projective
- namespace
- sofa::component::constraint::projective
- include
- sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h
- inherits
-
- ProjectiveConstraintSet
- templates
-
- sofa::defaulttype::Rigid3Types
- sofa::defaulttype::Vec3Types
- description
The PositionBasedDynamicsProjectiveConstraint is designed to enforce position-based dynamics (PBD) constraints within the SOFA framework. It operates by blending current positions towards target positions and updating velocities based on these adjustments. The mathematical formulation and physical principles are described below.
Governing Equations and Operators
Position Update Equation
The primary equation implemented in this component is a position update rule that blends between the current position $\mathbf{x}(t)$ and the target position $ar{oldsymbol{X}}$:
egin{equation}
oldsymbol{x}(t) = oldsymbol{x}(t) + k (ar{oldsymbol{X}} - oldsymbol{x}(t))
ag{1}
ext{(for vector or scalar positions)}
ext{where } \boldsymbol{x} \in ext{Vec3, Vec2, Vec1, Rigid3},\end{equation}
and the stiffness parameter $k$ controls how much the current position is blended towards the target. The component ensures that if $k = 1 ext{, then } oldsymbol{x}(t) = ar{oldsymbol{X}}.
#### Velocity Update Equation
The velocity update equation is derived from the new position and previous positions:
egin{equation}
oldsymbol{v}(t) = \frac{oldsymbol{x}(t) - oldsymbol{x}(t-1)}{ ext{dt}},
ag{2}
where \(oldsymbol{x}(t) ext{ is the new position, }\boldsymbol{x}(t-1)$ is the old position, and $ ext{dt}$ is the time step. For non-zero stiffness:
egin{equation}
oldsymbol{v}(t) = oldsymbol{v}(t) + k ( ar{oldsymbol{X}} - oldsymbol{x}(t)) / ext{dt}.
ag{3}
Constitutive or Kinematic Laws Involved
The component does not involve traditional constitutive laws, such as stress-strain relationships from elasticity. Instead, it relies on the following kinematic principles:
- Position-based Dynamics (PBD): The primary law governing this constraint is the position update described above.
- Velocity Computation: Velocities are updated based on the difference between the current and previous positions, as shown in Equation 2.
Role in the Global FEM Pipeline
In terms of its role within the broader Finite Element Method (FEM) pipeline:
- The component handles position and velocity updates directly through the projectPosition and projectVelocity methods. This is part of the nonlinear solve phase, as it affects how positions are corrected in each time step.
- It does not contribute to the construction or assembly of global matrices (mass matrix $M$, stiffness matrix $K$, etc.), but rather modifies the nodal positions and velocities directly. This is a key difference from traditional FEM constraints, which often influence these matrices.
Numerical Methods and Discretization Choices
The component uses the following numerical methods:
- Explicit blending: Positions are updated explicitly according to Equation 1, avoiding any need for solving large linear systems.
- Time discretization: Velocities are computed based on the difference between new and old positions, which is a form of explicit time integration (Equation 2).
Integration into Variational/Lagrangian Mechanics Framework
While the PBD approach does not directly arise from variational principles or Lagrangian mechanics in its formulation, it can be seen as an approximation that aims to enforce constraints efficiently. In the broader context:
- The method provides a way to project positions and velocities back onto desired configurations (target positions) at each time step.
- By blending towards target positions and updating velocities accordingly, the component ensures that the system evolves in a physically plausible manner without solving complex nonlinear equations.
Summary of Key Contributions
The PositionBasedDynamicsProjectiveConstraint enforces position-based dynamics by directly manipulating nodal positions and computing new velocities based on those updates. It does not rely on traditional constitutive laws or large-scale matrix manipulations, instead focusing on direct positional adjustments in each time step to maintain physical consistency.
Data Fields
| Name | Type | Default | Help |
|---|---|---|---|
data |
DataTypes | |
|
d_stiffness |
Real | |
Blending between current pos and target pos. |
d_position |
VecCoord | |
Target positions. |
d_velocity |
VecDeriv | |
Velocities. |
d_old_position |
VecCoord | |
Old positions. |
Methods
void
init
()
void
reset
()
void
projectResponse
(const core::MechanicalParams * , DataVecDeriv & )
void
projectVelocity
(const core::MechanicalParams * mparams, DataVecDeriv & vData)
void
projectPosition
(const core::MechanicalParams * mparams, DataVecCoord & xData)
void
projectJacobianMatrix
(const core::MechanicalParams * mparams, DataMatrixDeriv & cData)
void
handleTopologyChange
()
{
"name": "PositionBasedDynamicsProjectiveConstraint",
"namespace": "sofa::component::constraint::projective",
"module": "Sofa.Component.Constraint.Projective",
"include": "sofa/component/constraint/projective/PositionBasedDynamicsProjectiveConstraint.h",
"doc": "Position-based dynamics\n\nPosition-based dynamics as described in [Muller06]:\ninput: target positions X\noutput : x(t) <- x(t) + stiffness.( X - x(t) )\n\t\t v(t) <- [ x(t) - x(t-1) ] / dt = v(t) + stiffness.( X - x(t) ) /dt",
"inherits": [
"ProjectiveConstraintSet"
],
"templates": [
"sofa::defaulttype::Rigid3Types",
"sofa::defaulttype::Vec3Types"
],
"data_fields": [
{
"name": "data",
"type": "DataTypes"
},
{
"name": "d_stiffness",
"type": "Real",
"xmlname": "stiffness",
"help": "Blending between current pos and target pos."
},
{
"name": "d_position",
"type": "VecCoord",
"xmlname": "position",
"help": "Target positions."
},
{
"name": "d_velocity",
"type": "VecDeriv",
"xmlname": "velocity",
"help": "Velocities."
},
{
"name": "d_old_position",
"type": "VecCoord",
"xmlname": "old_position",
"help": "Old positions."
}
],
"links": [],
"methods": [
{
"name": "init",
"return_type": "void",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "reset",
"return_type": "void",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "projectResponse",
"return_type": "void",
"params": [
{
"name": "",
"type": "const core::MechanicalParams *"
},
{
"name": "",
"type": "DataVecDeriv &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "projectVelocity",
"return_type": "void",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "vData",
"type": "DataVecDeriv &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "projectPosition",
"return_type": "void",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "xData",
"type": "DataVecCoord &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "projectJacobianMatrix",
"return_type": "void",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "cData",
"type": "DataMatrixDeriv &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "handleTopologyChange",
"return_type": "void",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
}
],
"description": "The `PositionBasedDynamicsProjectiveConstraint` is a projective constraint used in SOFA to implement position-based dynamics (PBD). This component ensures that the positions and velocities of elements are adjusted according to target positions, as described by [Muller06]. It inherits from `core::behavior::ProjectiveConstraintSet`, enabling it to operate within the mechanical simulation framework. The constraint blends between current positions and target positions based on a specified stiffness parameter.\n\nThe component interacts with other SOFA components through its API methods such as `projectPosition` and `projectVelocity`. These methods update the positions and velocities of elements in accordance with PBD principles, using the target positions provided via the `d_position` field. The `stiffness` field controls how much the current position is blended towards the target.\n\nPractical usage involves setting the target positions (`d_position`) and specifying a stiffness value to control the blending between current and target positions. Additional fields include `velocity`, which stores velocity data, and `old_position`, storing previous positions for computing velocities.",
"maths": "The `PositionBasedDynamicsProjectiveConstraint` is designed to enforce position-based dynamics (PBD) constraints within the SOFA framework. It operates by blending current positions towards target positions and updating velocities based on these adjustments. The mathematical formulation and physical principles are described below.\n\n### Governing Equations and Operators\n\n#### Position Update Equation\nThe primary equation implemented in this component is a position update rule that blends between the current position \\(\\mathbf{x}(t)\\) and the target position \\(\bar{\boldsymbol{X}}\\):\n\begin{equation}\n \boldsymbol{x}(t) = \boldsymbol{x}(t) + k (\bar{\boldsymbol{X}} - \boldsymbol{x}(t))\n\tag{1}\n\text{(for vector or scalar positions)}\n\text{where } \\boldsymbol{x} \\in \text{Vec3, Vec2, Vec1, Rigid3},\\end{equation}\n\nand the stiffness parameter \\(k\\) controls how much the current position is blended towards the target. The component ensures that if \\(k = 1\text{, then } \boldsymbol{x}(t) = \bar{\boldsymbol{X}}.\n\n#### Velocity Update Equation\nThe velocity update equation is derived from the new position and previous positions:\n\begin{equation}\n \boldsymbol{v}(t) = \\frac{\boldsymbol{x}(t) - \boldsymbol{x}(t-1)}{\text{dt}},\n\tag{2}\n\nwhere \\(\boldsymbol{x}(t)\text{ is the new position, }\\boldsymbol{x}(t-1)\\) is the old position, and \\(\text{dt}\\) is the time step. For non-zero stiffness:\n\begin{equation}\n \boldsymbol{v}(t) = \boldsymbol{v}(t) + k ( \bar{\boldsymbol{X}} - \boldsymbol{x}(t)) / \text{dt}.\n\tag{3}\n\n### Constitutive or Kinematic Laws Involved\nThe component does not involve traditional constitutive laws, such as stress-strain relationships from elasticity. Instead, it relies on the following kinematic principles:\n- **Position-based Dynamics (PBD):** The primary law governing this constraint is the position update described above.\n- **Velocity Computation:** Velocities are updated based on the difference between the current and previous positions, as shown in Equation 2.\n\n### Role in the Global FEM Pipeline\nIn terms of its role within the broader Finite Element Method (FEM) pipeline:\n- The component handles position and velocity updates directly through the `projectPosition` and `projectVelocity` methods. This is part of the **nonlinear solve** phase, as it affects how positions are corrected in each time step.\n- It does not contribute to the construction or assembly of global matrices (mass matrix \\(M\\), stiffness matrix \\(K\\), etc.), but rather modifies the nodal positions and velocities directly. This is a key difference from traditional FEM constraints, which often influence these matrices.\n\n### Numerical Methods and Discretization Choices\nThe component uses the following numerical methods:\n- **Explicit blending:** Positions are updated explicitly according to Equation 1, avoiding any need for solving large linear systems.\n- **Time discretization:** Velocities are computed based on the difference between new and old positions, which is a form of explicit time integration (Equation 2).\n\n### Integration into Variational/Lagrangian Mechanics Framework\nWhile the PBD approach does not directly arise from variational principles or Lagrangian mechanics in its formulation, it can be seen as an approximation that aims to enforce constraints efficiently. In the broader context:\n- The method provides a way to project positions and velocities back onto desired configurations (target positions) at each time step.\n- By blending towards target positions and updating velocities accordingly, the component ensures that the system evolves in a physically plausible manner without solving complex nonlinear equations.\n\n### Summary of Key Contributions\nThe `PositionBasedDynamicsProjectiveConstraint` enforces position-based dynamics by directly manipulating nodal positions and computing new velocities based on those updates. It does not rely on traditional constitutive laws or large-scale matrix manipulations, instead focusing on direct positional adjustments in each time step to maintain physical consistency.",
"abstract": "The PositionBasedDynamicsProjectiveConstraint enforces position-based dynamics by blending current positions towards target positions based on a specified stiffness parameter and updating velocities accordingly.",
"sheet": "# PositionBasedDynamicsProjectiveConstraint\n\n## Overview\nThe `PositionBasedDynamicsProjectiveConstraint` is a projective constraint that implements position-based dynamics (PBD) in SOFA. It updates the positions and velocities of elements according to target positions provided via the `d_position` field, using a stiffness parameter (`stiffness`) to control the blending between current and target positions.\n\n## Mathematical Model\nThe component enforces PBD constraints by updating positions and velocities based on the following equations:\n\n### Position Update Equation\n\begin{equation}\n \boldsymbol{x}(t) = \boldsymbol{x}(t) + k (\bar{\boldsymbol{X}} - \boldsymbol{x}(t)) \\tag{1}\n\\end{equation}\nwhere $k$ is the stiffness parameter, $\boldsymbol{x}(t)$ is the current position, and $\bar{\boldsymbol{X}}$ is the target position.\n\n### Velocity Update Equation\n\begin{equation}\n \boldsymbol{v}(t) = \\frac{\boldsymbol{x}(t) - \boldsymbol{x}(t-1)}{dt} \\tag{2}\n\\end{equation}\nwhere $\boldsymbol{x}(t)$ is the new position, $\boldsymbol{x}(t-1)$ is the old position, and $dt$ is the time step. For non-zero stiffness:\n\begin{equation}\n \boldsymbol{v}(t) = \boldsymbol{v}(t) + k ( \bar{\boldsymbol{X}} - \boldsymbol{x}(t)) / dt \\tag{3}\n\\end{equation}\n\n## Parameters and Data\n- **stiffness**: Blending between current position and target position. Type: Real.\n- **position**: Target positions. Type: VecCoord.\n- **velocity**: Velocities. Type: VecDeriv.\n- **old_position**: Old positions for computing velocities. Type: VecCoord.\n\n## Practical Notes\nThe stiffness parameter controls how strongly the current position is blended towards the target position. Setting a high stiffness value can lead to rapid convergence but may also cause numerical instability if not carefully chosen."
}