Back

TriangularFEMForceFieldOptim

sofa::component::solidmechanics::fem::elastic::TriangularFEMForceFieldOptim
BaseLinearElasticityFEMForceField
Doc (from source)

Corotational Triangular finite elements. corotational triangle from @InProceedings{NPF05, author = "Nesme, Matthieu and Payan, Yohan and Faure, Fran\c{c}ois", title = "Efficient, Physically Plausible Finite Elements", booktitle = "Eurographics (short papers)", month = "august", year = "2005", editor = "J. Dingliana and F. Ganovelli", keywords = "animation, physical model, elasticity, finite elements", url = "http://www-evasion.imag.fr/Publications/2005/NPF05" }

Abstract (AI generated)

The `TriangularFEMForceFieldOptim` component simulates corotational triangular finite elements for linear elasticity in SOFA, handling forces, stiffness matrices, and stress computations with parameters for damping and rest scaling.

Metadata
module
Sofa.Component.SolidMechanics.FEM.Elastic
namespace
sofa::component::solidmechanics::fem::elastic
include
sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h
inherits
  • BaseLinearElasticityFEMForceField
templates
  • sofa::defaulttype::Vec3Types
description

Mathematical and Physical Description of TriangularFEMForceFieldOptim

Governing Equations and Operators:

  • Internal Force: The internal force for each triangular element is computed using the corotational formulation. For triangle $ T_i $ with nodes indexed as $[i_1, i_2, i_3]$, the forces at these nodes are derived from the stress-strain relationship and rotations around the centroid of the triangle.

  • Stress-Strain Relationship: The constitutive law used is linear elasticity. Given Young's modulus $ E $ and Poisson’s ratio $ u $, the Lame parameters ($μ, λ$) are computed as:
    $$μ = \frac{E}{2(1 + ν)}, λ = \frac{Eν}{(1 + ν)(1 - 2ν)}$$

  • Strain Displacement Matrix: The strain-displacement matrix for a triangle is given by:
    $$ B_i = \begin{bmatrix} b_{i,1} & 0 \\ 0 & b_{i,2} \\ -c_{i,1} & c_{i,2} \end{bmatrix},$$

where
$$ b_{i,1} = \begin{bmatrix} β_2 & β_3 & -(β_2 + β_3) \end{bmatrix},$$

and
$$ b_{i,2} = \begin{bmatrix} γ_2 & γ_3 & -(γ_2 + γ_3) \end{bmatrix}.$$

  • Stiffness Matrix: The stiffness matrix is derived from the strain-displacement matrix and material properties, resulting in a block-diagonal matrix for each triangle:
    $$ K_{T_i} = B_i^T D B_i.$$

Where $D$ is the material compliance tensor given by linear elasticity.

  • Residual Calculation: The nonlinear residual calculation involves evaluating forces and their derivatives with respect to displacements, forming a system of equations:
    $$ R(x_{k+1}) = M \frac{x_{k+1} - x_k}{Δt} + Δt f_{int}(x_{k+1}) - Δt f_{ext}.$$

Constitutive and Kinematic Laws:

  • Strain Measures: The strains are computed in the local frame of each triangle, accounting for rotations. This is achieved by transforming displacements into a local coordinate system defined by the rotation matrix $R_i$.
  • Local displacement: $ u_{local} = R_i^T (u_i - u_0) $

  • Stress Tensors: The stress tensor for each triangle is computed from the strains using Hooke’s Law, modified to account for linear elasticity:
    $$ σ = D : ε(u_{local}),$$

where $D$ is a symmetric matrix derived from Young's modulus and Poisson's ratio.

  • Hyperelastic Potential: Although the component focuses on linear elasticity, it can handle small deformations under large rotations. The potential energy for each triangle can be expressed as:
    $$ W = ∇W(ε),$$

where $ W $ is the strain energy density and $ ε $ is the strain tensor.

Role in the FEM Pipeline:

  • Assembly Phase: The component assembles global internal forces, stiffness matrices, and damping matrices by aggregating contributions from individual triangles. This includes handling constraints and projections of stresses within each triangle.

  • Time Integration: It supports implicit time integration schemes such as Backward Euler to advance the state in time, ensuring stability for nonlinear dynamics:
    $$ \frac{x_{n+1} - x_n}{Δt} = v_{n+1},$$

where $v_{n+1}$ is the velocity at the next time step.

  • Nonlinear Resolution: The component utilizes Newton-Raphson iteration to solve for nonlinear residuals, updating displacements iteratively:
    $$ R(x_k + δ x_k) = J(x_k)δ x_k.$$

Numerical Methods and Discretization Choices:

  • Corotational Formulation: This formulation accounts for rotations around the centroid of each triangular element, ensuring numerical stability even with large deformations.

  • Gauss Integration: While not explicitly mentioned in this component, Gauss quadrature is commonly used for integration over triangle elements to compute stiffness and force contributions accurately.

Variational Mechanics Framework:

The TriangularFEMForceFieldOptim fits into the broader Lagrangian mechanics framework by discretizing weak forms and solving them variationally. It ensures mechanical invariants are preserved through consistent mappings of rotations and strains within each triangle, leading to physically plausible deformations.

Data Fields
NameTypeDefaultHelp
d_damping Real Ratio damping/stiffness
d_restScale Real Scale factor applied to rest positions (to simulate pre-stretched materials)
d_computePrincipalStress bool Compute principal stress for each triangle
d_stressMaxValue Real Max stress value computed over the triangulation
d_showStressVector bool Flag activating rendering of stress directions within each triangle
d_showStressThreshold Real Threshold value to render only stress vectors higher to this threshold
Methods
void init ()
void reinit ()
void addForce (const core::MechanicalParams * mparams, DataVecDeriv & f, const DataVecCoord & x, const DataVecDeriv & v)
void addDForce (const core::MechanicalParams * mparams, DataVecDeriv & df, const DataVecDeriv & dx)
void addKToMatrix (sofa::linearalgebra::BaseMatrix * matrix, SReal kFact, unsigned int & offset)
void buildStiffnessMatrix (core::behavior::StiffnessMatrix * matrix)
void buildDampingMatrix (core::behavior::DampingMatrix * )
SReal getPotentialEnergy (const core::MechanicalParams * mparams, const DataVecCoord & x)
void computePrincipalStress ()
void getTrianglePrincipalStress (Index i, Real & stressValue, Deriv & stressDirection)
void computeBBox (const core::ExecParams * params, bool onlyVisible)
void draw (const core::visual::VisualParams * vparams)
void parse (sofa::core::objectmodel::BaseObjectDescription * arg)
void createTriangleInfo (Index triangleIndex, TriangleInfo & , const Triangle & t, const int & , const int & )
void createTriangleState (Index triangleIndex, TriangleState & , const Triangle & t, const int & , const int & )
void initTriangleInfo (Index triangleIndex, TriangleInfo & ti, const Triangle t, const VecCoord & x0)
void initTriangleState (Index triangleIndex, TriangleState & ti, const Triangle t, const VecCoord & x)
void computeTriangleRotation (Transformation & result, Coord eab, Coord eac)
void computeTriangleRotation (Transformation & result, Coord a, Coord b, Coord c)
void computeTriangleRotation (Transformation & result, VecCoord & x0, Triangle t)
void getTriangleVonMisesStress (Index i, Real & stressValue)
void getTrianglePrincipalStress (Index i, Real & stressValue, Deriv & stressDirection, Real & stressValue2, Deriv & stressDirection2)
int getRotatedInitialElement (Index elemId)
Transformation getRotationMatrix (Index elemId)
MaterialStiffness getMaterialStiffness (Index elemId)
type::Vec3 getStrainDisplacementFactors (Index elemId)
Real getTriangleFactor (Index elemId)
std::pair<Real, Real> computeMuGamma (Real youngModulus, Real poissonRatio)
{
  "name": "TriangularFEMForceFieldOptim",
  "namespace": "sofa::component::solidmechanics::fem::elastic",
  "module": "Sofa.Component.SolidMechanics.FEM.Elastic",
  "include": "sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h",
  "doc": "Corotational Triangular finite elements.\n\ncorotational triangle from\n@InProceedings{NPF05,\n  author       = \"Nesme, Matthieu and Payan, Yohan and Faure, Fran\\c{c}ois\",\n  title        = \"Efficient, Physically Plausible Finite Elements\",\n  booktitle    = \"Eurographics (short papers)\",\n  month        = \"august\",\n  year         = \"2005\",\n  editor       = \"J. Dingliana and F. Ganovelli\",\n  keywords     = \"animation, physical model, elasticity, finite elements\",\n  url          = \"http://www-evasion.imag.fr/Publications/2005/NPF05\"\n}",
  "inherits": [
    "BaseLinearElasticityFEMForceField"
  ],
  "templates": [
    "sofa::defaulttype::Vec3Types"
  ],
  "data_fields": [
    {
      "name": "d_damping",
      "type": "Real",
      "xmlname": "damping",
      "help": "Ratio damping/stiffness"
    },
    {
      "name": "d_restScale",
      "type": "Real",
      "xmlname": "restScale",
      "help": "Scale factor applied to rest positions (to simulate pre-stretched materials)"
    },
    {
      "name": "d_computePrincipalStress",
      "type": "bool",
      "xmlname": "computePrincipalStress",
      "help": "Compute principal stress for each triangle"
    },
    {
      "name": "d_stressMaxValue",
      "type": "Real",
      "xmlname": "stressMaxValue",
      "help": "Max stress value computed over the triangulation"
    },
    {
      "name": "d_showStressVector",
      "type": "bool",
      "xmlname": "showStressVector",
      "help": "Flag activating rendering of stress directions within each triangle"
    },
    {
      "name": "d_showStressThreshold",
      "type": "Real",
      "xmlname": "showStressThreshold",
      "help": "Threshold value to render only stress vectors higher to this threshold"
    }
  ],
  "links": [],
  "methods": [
    {
      "name": "init",
      "return_type": "void",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "reinit",
      "return_type": "void",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "addForce",
      "return_type": "void",
      "params": [
        {
          "name": "mparams",
          "type": "const core::MechanicalParams *"
        },
        {
          "name": "f",
          "type": "DataVecDeriv &"
        },
        {
          "name": "x",
          "type": "const DataVecCoord &"
        },
        {
          "name": "v",
          "type": "const DataVecDeriv &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "addDForce",
      "return_type": "void",
      "params": [
        {
          "name": "mparams",
          "type": "const core::MechanicalParams *"
        },
        {
          "name": "df",
          "type": "DataVecDeriv &"
        },
        {
          "name": "dx",
          "type": "const DataVecDeriv &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "addKToMatrix",
      "return_type": "void",
      "params": [
        {
          "name": "matrix",
          "type": "sofa::linearalgebra::BaseMatrix *"
        },
        {
          "name": "kFact",
          "type": "SReal"
        },
        {
          "name": "offset",
          "type": "unsigned int &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "buildStiffnessMatrix",
      "return_type": "void",
      "params": [
        {
          "name": "matrix",
          "type": "core::behavior::StiffnessMatrix *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "buildDampingMatrix",
      "return_type": "void",
      "params": [
        {
          "name": "",
          "type": "core::behavior::DampingMatrix *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getPotentialEnergy",
      "return_type": "SReal",
      "params": [
        {
          "name": "mparams",
          "type": "const core::MechanicalParams *"
        },
        {
          "name": "x",
          "type": "const DataVecCoord &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computePrincipalStress",
      "return_type": "void",
      "params": [],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getTrianglePrincipalStress",
      "return_type": "void",
      "params": [
        {
          "name": "i",
          "type": "Index"
        },
        {
          "name": "stressValue",
          "type": "Real &"
        },
        {
          "name": "stressDirection",
          "type": "Deriv &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeBBox",
      "return_type": "void",
      "params": [
        {
          "name": "params",
          "type": "const core::ExecParams *"
        },
        {
          "name": "onlyVisible",
          "type": "bool"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "draw",
      "return_type": "void",
      "params": [
        {
          "name": "vparams",
          "type": "const core::visual::VisualParams *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "parse",
      "return_type": "void",
      "params": [
        {
          "name": "arg",
          "type": "sofa::core::objectmodel::BaseObjectDescription *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "createTriangleInfo",
      "return_type": "void",
      "params": [
        {
          "name": "triangleIndex",
          "type": "Index"
        },
        {
          "name": "",
          "type": "TriangleInfo &"
        },
        {
          "name": "t",
          "type": "const Triangle &"
        },
        {
          "name": "",
          "type": "const int &"
        },
        {
          "name": "",
          "type": "const int &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "createTriangleState",
      "return_type": "void",
      "params": [
        {
          "name": "triangleIndex",
          "type": "Index"
        },
        {
          "name": "",
          "type": "TriangleState &"
        },
        {
          "name": "t",
          "type": "const Triangle &"
        },
        {
          "name": "",
          "type": "const int &"
        },
        {
          "name": "",
          "type": "const int &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "initTriangleInfo",
      "return_type": "void",
      "params": [
        {
          "name": "triangleIndex",
          "type": "Index"
        },
        {
          "name": "ti",
          "type": "TriangleInfo &"
        },
        {
          "name": "t",
          "type": "const Triangle"
        },
        {
          "name": "x0",
          "type": "const VecCoord &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "initTriangleState",
      "return_type": "void",
      "params": [
        {
          "name": "triangleIndex",
          "type": "Index"
        },
        {
          "name": "ti",
          "type": "TriangleState &"
        },
        {
          "name": "t",
          "type": "const Triangle"
        },
        {
          "name": "x",
          "type": "const VecCoord &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeTriangleRotation",
      "return_type": "void",
      "params": [
        {
          "name": "result",
          "type": "Transformation &"
        },
        {
          "name": "eab",
          "type": "Coord"
        },
        {
          "name": "eac",
          "type": "Coord"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeTriangleRotation",
      "return_type": "void",
      "params": [
        {
          "name": "result",
          "type": "Transformation &"
        },
        {
          "name": "a",
          "type": "Coord"
        },
        {
          "name": "b",
          "type": "Coord"
        },
        {
          "name": "c",
          "type": "Coord"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeTriangleRotation",
      "return_type": "void",
      "params": [
        {
          "name": "result",
          "type": "Transformation &"
        },
        {
          "name": "x0",
          "type": "VecCoord &"
        },
        {
          "name": "t",
          "type": "Triangle"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getTriangleVonMisesStress",
      "return_type": "void",
      "params": [
        {
          "name": "i",
          "type": "Index"
        },
        {
          "name": "stressValue",
          "type": "Real &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getTrianglePrincipalStress",
      "return_type": "void",
      "params": [
        {
          "name": "i",
          "type": "Index"
        },
        {
          "name": "stressValue",
          "type": "Real &"
        },
        {
          "name": "stressDirection",
          "type": "Deriv &"
        },
        {
          "name": "stressValue2",
          "type": "Real &"
        },
        {
          "name": "stressDirection2",
          "type": "Deriv &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getRotatedInitialElement",
      "return_type": "int",
      "params": [
        {
          "name": "elemId",
          "type": "Index"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getRotationMatrix",
      "return_type": "Transformation",
      "params": [
        {
          "name": "elemId",
          "type": "Index"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getMaterialStiffness",
      "return_type": "MaterialStiffness",
      "params": [
        {
          "name": "elemId",
          "type": "Index"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getStrainDisplacementFactors",
      "return_type": "type::Vec3",
      "params": [
        {
          "name": "elemId",
          "type": "Index"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "getTriangleFactor",
      "return_type": "Real",
      "params": [
        {
          "name": "elemId",
          "type": "Index"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeMuGamma",
      "return_type": "std::pair<Real, Real>",
      "params": [
        {
          "name": "youngModulus",
          "type": "Real"
        },
        {
          "name": "poissonRatio",
          "type": "Real"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": true,
      "access": "protected"
    }
  ],
  "description": "The `TriangularFEMForceFieldOptim` is a specialized force field component in the SOFA framework, designed for corotational triangular finite elements. It inherits from `BaseLinearElasticityFEMForceField`, indicating its role in simulating linear elasticity forces within solid mechanics applications.\n\nThis component handles topology and mesh information via connections to a linked Topology container and can compute forces, stiffness matrices, and damping matrices for each triangle in the mesh. The force computation uses a corotational formulation that accounts for rotations around the centroid of each triangular element. This allows it to handle large deformations while maintaining numerical stability.\n\nThe component includes data fields such as `d_damping` (ratio of damping to stiffness), `d_restScale` (scale factor applied to rest positions), and several flags and values related to stress computation and rendering, like `computePrincipalStress`, `stressMaxValue`, `showStressVector`, and `showStressThreshold`. These settings allow customization for specific simulation needs, such as visualizing principal stresses within the triangles.\n\nThe component provides various methods to compute internal forces (`addForce`), derivative forces with respect to displacements (`addDForce`), stiffness matrices (`buildStiffnessMatrix`, `addKToMatrix`), and additional utility functions like stress computation and rendering. It also handles topology modifications through creation callbacks for triangle data.\n\nIn summary, the `TriangularFEMForceFieldOptim` is a powerful tool within SOFA for simulating elastic forces in deformable objects using triangular finite elements with corotational formulations.",
  "maths": "### Mathematical and Physical Description of `TriangularFEMForceFieldOptim`\n\n#### Governing Equations and Operators:\n\n- **Internal Force:** The internal force for each triangular element is computed using the corotational formulation. For triangle \\( T_i \\) with nodes indexed as \\([i_1, i_2, i_3]\\), the forces at these nodes are derived from the stress-strain relationship and rotations around the centroid of the triangle.\n\n- **Stress-Strain Relationship:** The constitutive law used is linear elasticity. Given Young's modulus \\( E \\) and Poisson’s ratio \\( \nu \\), the Lame parameters (\\(μ, λ\\)) are computed as:\n  \\[μ = \\frac{E}{2(1 + ν)},\n  λ = \\frac{Eν}{(1 + ν)(1 - 2ν)}\\]\n\n- **Strain Displacement Matrix:** The strain-displacement matrix for a triangle is given by:\n  \\[ B_i =\n  \\begin{bmatrix}\n    b_{i,1} & 0 \\\\ 0 & b_{i,2} \\\\ -c_{i,1} & c_{i,2}\n  \\end{bmatrix},\\]\n  where\n  \\[ b_{i,1} =\n  \\begin{bmatrix}\n    β_2 & β_3 & -(β_2 + β_3)\n  \\end{bmatrix},\\]\n  and\n  \\[ b_{i,2} =\n  \\begin{bmatrix}\n    γ_2 & γ_3 & -(γ_2 + γ_3)\n  \\end{bmatrix}.\\]\n\n- **Stiffness Matrix:** The stiffness matrix is derived from the strain-displacement matrix and material properties, resulting in a block-diagonal matrix for each triangle:\n  \\[ K_{T_i} = B_i^T D B_i.\\]\n  Where \\(D\\) is the material compliance tensor given by linear elasticity.\n\n- **Residual Calculation:** The nonlinear residual calculation involves evaluating forces and their derivatives with respect to displacements, forming a system of equations:\n  \\[ R(x_{k+1}) = M \\frac{x_{k+1} - x_k}{Δt} + Δt f_{int}(x_{k+1}) - Δt f_{ext}.\\]\n\n#### Constitutive and Kinematic Laws:\n\n- **Strain Measures:** The strains are computed in the local frame of each triangle, accounting for rotations. This is achieved by transforming displacements into a local coordinate system defined by the rotation matrix \\(R_i\\).\n  - Local displacement: \\( u_{local} = R_i^T (u_i - u_0) \\)\n\n- **Stress Tensors:** The stress tensor for each triangle is computed from the strains using Hooke’s Law, modified to account for linear elasticity:\n  \\[ σ = D : ε(u_{local}),\\]\n  where \\(D\\) is a symmetric matrix derived from Young's modulus and Poisson's ratio.\n\n- **Hyperelastic Potential:** Although the component focuses on linear elasticity, it can handle small deformations under large rotations. The potential energy for each triangle can be expressed as:\n  \\[ W = ∇W(ε),\\]\n  where \\( W \\) is the strain energy density and \\( ε \\) is the strain tensor.\n\n#### Role in the FEM Pipeline:\n\n- **Assembly Phase:** The component assembles global internal forces, stiffness matrices, and damping matrices by aggregating contributions from individual triangles. This includes handling constraints and projections of stresses within each triangle.\n\n- **Time Integration:** It supports implicit time integration schemes such as Backward Euler to advance the state in time, ensuring stability for nonlinear dynamics:\n  \\[ \\frac{x_{n+1} - x_n}{Δt} = v_{n+1},\\]\n  where \\(v_{n+1}\\) is the velocity at the next time step.\n\n- **Nonlinear Resolution:** The component utilizes Newton-Raphson iteration to solve for nonlinear residuals, updating displacements iteratively:\n  \\[ R(x_k + δ x_k) = J(x_k)δ x_k.\\]\n\n#### Numerical Methods and Discretization Choices:\n\n- **Corotational Formulation:** This formulation accounts for rotations around the centroid of each triangular element, ensuring numerical stability even with large deformations.\n\n- **Gauss Integration:** While not explicitly mentioned in this component, Gauss quadrature is commonly used for integration over triangle elements to compute stiffness and force contributions accurately.\n\n#### Variational Mechanics Framework:\n\nThe `TriangularFEMForceFieldOptim` fits into the broader Lagrangian mechanics framework by discretizing weak forms and solving them variationally. It ensures mechanical invariants are preserved through consistent mappings of rotations and strains within each triangle, leading to physically plausible deformations.\n",
  "abstract": "The `TriangularFEMForceFieldOptim` component simulates corotational triangular finite elements for linear elasticity in SOFA, handling forces, stiffness matrices, and stress computations with parameters for damping and rest scaling.",
  "sheet": "# TriangularFEMForceFieldOptim\n\n## Overview\n\nThe `TriangularFEMForceFieldOptim` is a specialized force field component designed to simulate corotational triangular finite elements within the SOFA framework. It inherits from `BaseLinearElasticityFEMForceField`, indicating its role in simulating linear elasticity forces and stiffness matrices for deformable objects.\n\n## Mathematical Model\n\nThe internal force for each triangular element is computed using a corotational formulation, which accounts for rotations around the centroid of each triangle. The constitutive law used is linear elasticity with Young's modulus $E$ and Poisson’s ratio $\nu$. The Lame parameters are given by:\n\\[ \\mu = \\frac{E}{2(1 + \nu)}, \\quad \\lambda = \\frac{E\nu}{(1 + \nu)(1 - 2\nu)} \\]\n\nThe strain-displacement matrix for a triangle is defined as:\n\\[\nB_i =\n\\begin{bmatrix}\nb_{i,1} & 0 \\\\ 0 & b_{i,2} \\\\ -c_{i,1} & c_{i,2}\n\\end{bmatrix},\n\\]\nwhere\n\\[ b_{i,1} = \\begin{bmatrix} β_2 & β_3 & -(β_2 + β_3) \\end{bmatrix}, \\quad b_{i,2} = \\begin{bmatrix} γ_2 & γ_3 & -(γ_2 + γ_3) \\end{bmatrix}.\\]\n\nThe stiffness matrix is derived from the strain-displacement matrix and material properties:\n\\[ K_{T_i} = B_i^T D B_i,\\]\nwhere $D$ is the material compliance tensor given by linear elasticity.\n\n## Parameters and Data\n\n- **d_damping**: Ratio of damping to stiffness. Type: `Real`.\n- **d_restScale**: Scale factor applied to rest positions (to simulate pre-stretched materials). Type: `Real`.\n- **computePrincipalStress**: Flag to compute principal stress for each triangle. Type: `bool`.\n- **stressMaxValue**: Maximum stress value computed over the triangulation. Type: `Real`.\n- **showStressVector**: Flag activating rendering of stress directions within each triangle. Type: `bool`.\n- **showStressThreshold**: Threshold value to render only stress vectors higher than this threshold. Type: `Real`."
}