Back

BaseLagrangianConstraint

sofa::core::behavior::BaseLagrangianConstraint
BaseConstraintSet
Doc (from source)

Component computing constraints within a simulated body. This class defines the abstract API common to all constraints. A BaseConstraint computes constraints applied to one or more simulated body given its current position and velocity. Constraints can be internal to a given body (attached to one MechanicalState, see the LagrangianConstraint class), or link several bodies together (such as contacts, see the InteractionConstraint class).

Abstract (AI generated)

`BaseLagrangianConstraint` is an abstract class defining the API for all constraints in SOFA simulations, managing constraint groups and information retrieval.

Metadata
module
Sofa.framework.Core
namespace
sofa::core::behavior
include
sofa/core/behavior/BaseLagrangianConstraint.h
inherits
  • BaseConstraintSet
description

Governing Equations and Operators

The
M \ddot{x}(t) + f_{int}(x(t)) = f_{ext}(t) component in the SOFA framework implements a force field that applies an outward or inward repulsion based on an ellipsoidal geometry to deformable objects. It contributes to the internal force vector
\end{equation}, which is part of the semi-discrete dynamical system equation:

egin{equation}
M \ddot{x}(t) + f_{int}(x(t)) = f_{ext}(t) component in the SOFA framework implements a force field that applies an outward or inward repulsion based on an ellipsoidal geometry to deformable objects. It contributes to the internal force vector
\end{equation}, which is part of the semi-discrete dynamical system equation:

where $$ J = \frac{\partial g(\mathbf{x})}{\partial \mathbf{x}} $$ is the mass matrix and $$ \lambda = J^T \cdot f_c $$ represents external forces.

The interaction force field computes the repulsive force at each point within or outside an ellipsoidal geometry. The repulsion force $\mathbf{p}_1$ at a point $\mathbf{p}_2$ relative to the ellipsoid center $d_0$ and semi-axes radii $J$ is given by:

egin{equation}
\mathbf{f}_i(\mathbf{p}_1) = -k \left(\sqrt{\frac{(\mathbf{p}_1 - \mathbf{c})_x^2}{r_x^2} + \frac{(\mathbf{p}_1 - \mathbf{c})_y^2}{r_y^2} + \frac{(\mathbf{p}_1 - \mathbf{c})_z^2}{r_z^2}} - 1\right) \left(\frac{(\mathbf{p}_1 - \mathbf{c})_x}{r_x^2}, \frac{(\mathbf{p}_1 - \mathbf{c})_y}{r_y^2}, \frac{(\mathbf{p}_1 - \mathbf{c})_z}{r_z^2}\right) / gnorm
\end{equation}

where $g(\mathbf{x})$ is the stiffness coefficient, and $f_c$ normalizes the direction.

Constitutive or Kinematic Laws Involved

The force model does not rely on a traditional constitutive law but rather an explicit geometric constraint. The repulsive force depends on the distance from each point to the ellipsoid surface, which is defined by:

egin{equation}
g(\mathbf{p}_1) = \sqrt{\frac{(\mathbf{p}_1 - \mathbf{c})_x^2}{r_x^2} + \frac{(\mathbf{p}_1 - \mathbf{c})_y^2}{r_y^2} + \frac{(\mathbf{p}_1 - \mathbf{c})_z^2}{r_z^2}} - 1
\end{equation}

The force $J^T$ is then a function of this distance and the stiffness coefficient, with damping optionally applied to velocity:

egin{equation}
f_{damping} = \beta v_i
\end{equation}

where is the velocity at point , and is the damping coefficient.

Role in the Global FEM Pipeline

  1. Initialization: The component initializes its internal variables, including ellipsoid center, radii, stiffness, and damping coefficients (initCalcF function).
  2. Force Calculation: It computes the repulsive forces for each point within or outside the ellipsoidal geometry relative to a reference frame defined by another object (addForce, calcF functions).
  3. Constraint Handling: The force is applied based on whether points lie inside or outside the ellipsoid, and the force direction depends on the sign of the stiffness coefficient.
  4. Time Integration: The calculated forces are part of the internal forces that enter the time integration scheme (addForce, addDForce functions).
  5. Nonlinear Solve: This component contributes to the nonlinear solve by providing a residual term through its force calculation (R(x) in the Newton-Raphson method).

Numerical Methods and Discretization Choices

The force field is computed at each node (point) of the deformed object, and the repulsion is based on an ellipsoid geometry. This geometric constraint ensures a nonlinear relationship between position and force.

  1. Geometric Transformation: Points are transformed into the local frame defined by another object (vars.pos6D) to ensure consistent relative positioning and orientation (addForce function).
  2. Residual Calculation: The residual is computed based on the difference between actual positions and those predicted under the influence of the repulsive force, which feeds into the nonlinear solve process.

  3. Matrix-Free Evaluation: While not explicitly forming a stiffness matrix, the component computes necessary derivatives for Newton-Raphson iterations (dfdx matrix in calcF).

Fit within Variational / Lagrangian Mechanics Framework

The InteractionEllipsoidForceField can be seen as implementing a form of geometric constraint that influences the potential energy of the system. The repulsion force acts to minimize this potential, which is consistent with variational principles:

egin{equation}

\delta U = \int_\Omega \mathbf{f}_{int} \cdot \delta \mathbf{x}\, d\Omega = 0

\end{equation}

The repulsion forces are derived from the distance to the ellipsoid surface and ensure that points inside (or outside) an object adhere to or diverge from the geometric constraint, thus contributing to the overall energy minimization.

Methods
const BaseLagrangianConstraint * toBaseLagrangianConstraint () virtual
int getGroup ()
void setGroup (int g)
void getConstraintInfo (const ConstraintParams * cParams, VecConstraintBlockInfo & blocks, VecPersistentID & ids) virtual
void getConstraintInfo (const core::ConstraintParams * cParams, VecConstraintBlockInfo & blocks, VecPersistentID & ids, VecConstCoord & positions, VecConstDeriv & directions, VecConstArea & areas) virtual
void getConstraintResolution (const ConstraintParams * cParams, int & resTab, unsigned int & offset) virtual
void getConstraintResolution (int & resTab, unsigned int & offset) virtual
int getIdentifiers ()
int getBaseConstraintIdentifiers ()
void storeLambda (const ConstraintParams * cParams, MultiVecDerivId res, const sofa::linearalgebra::BaseVector * lambda) virtual
{
  "name": "BaseLagrangianConstraint",
  "namespace": "sofa::core::behavior",
  "module": "Sofa.framework.Core",
  "include": "sofa/core/behavior/BaseLagrangianConstraint.h",
  "doc": "Component computing constraints within a simulated body.\n This class defines the abstract API common to all constraints.\n A BaseConstraint computes constraints applied to one or more simulated body\n given its current position and velocity.\n Constraints can be internal to a given body (attached to one MechanicalState,\n see the LagrangianConstraint class), or link several bodies together (such as contacts,\n see the InteractionConstraint class).",
  "inherits": [
    "BaseConstraintSet"
  ],
  "templates": [],
  "data_fields": [],
  "links": [],
  "methods": [
    {
      "name": "toBaseLagrangianConstraint",
      "return_type": "const BaseLagrangianConstraint *",
      "params": [],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getGroup",
      "return_type": "int",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "setGroup",
      "return_type": "void",
      "params": [
        {
          "name": "g",
          "type": "int"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getConstraintInfo",
      "return_type": "void",
      "params": [
        {
          "name": "cParams",
          "type": "const ConstraintParams *"
        },
        {
          "name": "blocks",
          "type": "VecConstraintBlockInfo &"
        },
        {
          "name": "ids",
          "type": "VecPersistentID &"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getConstraintInfo",
      "return_type": "void",
      "params": [
        {
          "name": "cParams",
          "type": "const core::ConstraintParams *"
        },
        {
          "name": "blocks",
          "type": "VecConstraintBlockInfo &"
        },
        {
          "name": "ids",
          "type": "VecPersistentID &"
        },
        {
          "name": "positions",
          "type": "VecConstCoord &"
        },
        {
          "name": "directions",
          "type": "VecConstDeriv &"
        },
        {
          "name": "areas",
          "type": "VecConstArea &"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getConstraintResolution",
      "return_type": "void",
      "params": [
        {
          "name": "cParams",
          "type": "const ConstraintParams *"
        },
        {
          "name": "resTab",
          "type": "int &"
        },
        {
          "name": "offset",
          "type": "unsigned int &"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getConstraintResolution",
      "return_type": "void",
      "params": [
        {
          "name": "resTab",
          "type": "int &"
        },
        {
          "name": "offset",
          "type": "unsigned int &"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getIdentifiers",
      "return_type": "int",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getBaseConstraintIdentifiers",
      "return_type": "int",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "storeLambda",
      "return_type": "void",
      "params": [
        {
          "name": "cParams",
          "type": "const ConstraintParams *"
        },
        {
          "name": "res",
          "type": "MultiVecDerivId"
        },
        {
          "name": "lambda",
          "type": "const sofa::linearalgebra::BaseVector *"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": true,
      "is_static": false,
      "access": "public"
    }
  ],
  "description": "The `BaseLagrangianConstraint` is an abstract class in the SOFA framework that serves as the foundation for all constraints applied to simulated bodies, whether internal or linking multiple bodies together (such as contacts). This component defines the API required for computing and handling these constraints. It inherits from `BaseConstraintSet`, providing a structure for managing constraint groups and their resolution within solvers.\n\n### Interactions with Other Components:\n- **Inheritance:** Inherits from `BaseConstraintSet` to manage constraint sets.\n- **Group Management:** The methods `getGroup()` and `setGroup(int g)` allow constraints to be categorized into different groups, which can then be solved by specific solvers based on these group IDs.\n- **Information Retrieval:** Abstract method `getConstraintInfo` provides information about the constraints, including positions and identifiers. This is crucial for solver algorithms that require detailed constraint data.\n- **Resolution Handling:** The methods `getConstraintResolution` manage the resolution of constraints within a simulation step, determining how constraints are solved given current state vectors and parameters.\n\n### Practical Usage Guidance:\n- Use this component as an abstract base class when implementing specific types of constraints (e.g., Lagrangian or interaction-based).\n- Implement the pure virtual methods `storeLambda` and `getBaseConstraintIdentifiers` to customize constraint resolution behavior for derived classes.\n- Utilize group management functions (`setGroup`, `getGroup`) to organize and control which solver handles specific constraint groups.",
  "maths": "<maths_md_description>\n\n## Mathematical and Physical Description of `BaseLagrangianConstraint`\n\n### Overview\nThe `BaseLagrangianConstraint` class serves as an abstract base for all constraints in the SOFA framework. Constraints are critical components that enforce specific conditions on the simulated bodies, ensuring they behave according to physical laws or predefined rules. This class inherits from `BaseConstraintSet`, providing a structure and interface for managing constraint sets.\n\n### Key Concepts\n#### Constraint Groups\nConstraints within the SOFA framework can be categorized into different groups using the methods:\n- `getGroup()`: Retrieves the group ID of the constraint.\n- `setGroup(int g)`: Sets the group ID of the constraint.\nThese group IDs are essential for specifying which solver handles which constraints, allowing for efficient and modular solving strategies.\n\n#### Constraint Information Retrieval\nThe method `getConstraintInfo` provides detailed information about each constraint. This includes:\n- **Parent Pointer**: A pointer to the parent `BaseConstraint`, indicating the origin of the constraint.\n- **Persistent IDs**: Unique identifiers for constraints, which are useful in tracking and resolving constraints across multiple simulation steps.\n- **Positions**: 3D positions associated with the constraints (e.g., contact points).\n\n#### Constraint Resolution\nThe methods `getConstraintResolution` manage how constraints are resolved within a simulation step:\n- These methods handle the addition of constraint resolution algorithms to a vector (`resTab`).\n- The offset parameter is used to specify the position in this vector where new resolution algorithms should be added.\n\n### Mathematical Formulation\nConstraints can mathematically be represented as equations that need to hold true at all times. For example, if a constraint requires a distance between two points to remain constant (distance constraint), it can be written as:\n$$\n\\mathbf{d}(t) = \\| \\mathbf{p}_1(t) - \\mathbf{p}_2(t) \\| - d_0 = 0\n$$\nwhere $\\mathbf{p}_1$ and $\\mathbf{p}_2$ are the positions of two points, and $d_0$ is the desired distance.\n\n#### Constraint Jacobian\nThe constraint Jacobian matrix $J$ contains partial derivatives of these constraints with respect to the generalized coordinates (positions and velocities). For example, for a position-based constraint:\n$$\nJ = \\frac{\\partial g(\\mathbf{x})}{\\partial \\mathbf{x}}\n$$\nwhere $g(\\mathbf{x})$ is the vector of constraints.\n\n#### Constraint Impulse Calculation\nThe method `storeLambda` stores the constraint lambda (impulses), which are computed as:\n$$\n\\lambda = J^T \\cdot f_c\n$$\nwhere $f_c$ represents the forces required to satisfy the constraints. The matrix $J^T$ is the transpose of the Jacobian.\n\n### Conclusion\nThe `BaseLagrangianConstraint` class provides a foundational structure for implementing and managing various types of constraints within SOFA simulations. It ensures that these constraints can be effectively categorized, retrieved, and resolved to maintain the physical integrity and behavior of simulated bodies.</maths_md_description>",
  "abstract": "`BaseLagrangianConstraint` is an abstract class defining the API for all constraints in SOFA simulations, managing constraint groups and information retrieval.",
  "sheet": "# BaseLagrangianConstraint\n\n## Overview\nThe `BaseLagrangianConstraint` serves as an abstract base class for all constraints within the SOFA framework. It inherits from `BaseConstraintSet`, providing a structure for managing constraint sets and defining methods to handle group management, information retrieval, and resolution.\n\n## Parameters and Data\n- **Group Management**: The methods `getGroup()` and `setGroup(int g)` allow constraints to be categorized into different groups, which can then be solved by specific solvers based on these group IDs.\n- **Constraint Information Retrieval**: Abstract method `getConstraintInfo` provides detailed information about the constraints, including positions and identifiers. This is crucial for solver algorithms that require detailed constraint data.\n- **Resolution Handling**: The methods `getConstraintResolution` manage how constraints are resolved within a simulation step, determining how constraints are solved given current state vectors and parameters."
}