Back

EulerExplicitSolver

The `EulerExplicitSolver` is an ODE (Ordinary Differential Equation) solver in the SOFA framework, designed for simple explicit time integration. This component provides two variants of Euler methods: **Forward Euler** and **Semi-Implicit Euler** (also known as Symplectic Euler). Both methods are used to solve motion equations by computing acceleration based on forces accumulated from force fields and mappings. The key feature distinguishing these methods is the update order of velocities and positions. When `symplectic` is set to `true`, the semi-implicit method updates velocities before positions, which is more robust for certain scenarios. Conversely, setting `symplectic` to `false` uses the forward Euler method, updating positions first. This solver interacts with other SOFA components through its API: - It inherits from `OdeSolver` and implements methods like `solve`, `getIntegrationFactor`, and `getSolutionIntegrationFactor`, which are critical for time integration. - A `LinearSolver` can be linked to handle more complex mass matrix scenarios, specifically when the mass matrix is not diagonal. Data fields allow customization of behavior: - `symplectic`: Controls the update order (default: true). - `threadSafeVisitor`: Ensures thread safety during operations (default: false). The solver uses a series of protected methods to compute forces, acceleration, and apply constraints. These methods collectively contribute to updating the mechanical state according to the chosen Euler method variant.

abstract
The `EulerExplicitSolver` implements explicit time integration using Forward Euler or Symplectic Euler methods to update positions and velocities based on computed accelerations from forces.
sheet
# EulerExplicitSolver ## Overview The `EulerExplicitSolver` is an ODE solver in the SOFA framework that provides two variants of the Euler method: **Forward Euler** (explicit) and **Symplectic Euler** (semi-implicit). It handles time integration by updating positions and velocities based on computed accelerations from forces. The component inherits from `OdeSolver` and can be linked with a `LinearSolver` for more complex mass matrix scenarios. ## Mathematical Model The `EulerExplicitSolver` implements the following methods: ### Forward Euler Method (Explicit) 1. **Update Acceleration**: \[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \] 2. **Update Velocity**: \[ v^{n+1} = v^n + dt imes a^{n+1} \] 3. **Update Position**: \[ q^{n+1} = q^n + dt imes v^{n+1} \] ### Symplectic Euler Method (Semi-Implicit) 1. **Update Acceleration**: \[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \] 2. **Update Velocity**: \[ v^{n+1} = v^n + dt imes a^{n+1} \] 3. **Update Position**: \[ q^{n+1} = q^n + dt imes v^{n+1} \] In both methods, $M^{-1}$ is the inverse of the mass matrix, which can be diagonal for simplicity. If the mass matrix is not diagonal, a `LinearSolver` component must handle its inversion and application to the force vector. ## Parameters and Data - **symplectic**: Controls the update order (default: true). When set to `true`, it uses the Symplectic Euler method; otherwise, it uses the Forward Euler method. - **threadSafeVisitor**: Ensures thread safety during operations (default: false). ## Dependencies and Connections The component typically requires a `LinearSolver` if the mass matrix is not diagonal. It interacts with force fields to accumulate forces and mappings to project forces of mapped objects.
description
The `EulerExplicitSolver` is an ODE (Ordinary Differential Equation) solver in the SOFA framework, designed for simple explicit time integration. This component provides two variants of Euler methods: **Forward Euler** and **Semi-Implicit Euler** (also known as Symplectic Euler). Both methods are used to solve motion equations by computing acceleration based on forces accumulated from force fields and mappings. The key feature distinguishing these methods is the update order of velocities and positions. When `symplectic` is set to `true`, the semi-implicit method updates velocities before positions, which is more robust for certain scenarios. Conversely, setting `symplectic` to `false` uses the forward Euler method, updating positions first. This solver interacts with other SOFA components through its API: - It inherits from `OdeSolver` and implements methods like `solve`, `getIntegrationFactor`, and `getSolutionIntegrationFactor`, which are critical for time integration. - A `LinearSolver` can be linked to handle more complex mass matrix scenarios, specifically when the mass matrix is not diagonal. Data fields allow customization of behavior: - `symplectic`: Controls the update order (default: true). - `threadSafeVisitor`: Ensures thread safety during operations (default: false). The solver uses a series of protected methods to compute forces, acceleration, and apply constraints. These methods collectively contribute to updating the mechanical state according to the chosen Euler method variant.
maths
## Mathematical and Physical Description of the EulerExplicitSolver Component The `EulerExplicitSolver` in the SOFA framework is designed for explicit time integration using two variants of the Euler method: **Forward Euler** (explicit) and **Symplectic Euler** (semi-implicit). These methods are widely used to solve ordinary differential equations (ODEs) arising from motion equations in physics-based simulations. The ODE system typically represents Newton's second law, which can be expressed as: \[ m \ddot{q}(t) = F(t, q(t), \dot{q}(t)) \] where: - $m$ is the mass matrix, - $q(t)$ are the generalized coordinates (position vector), - $\dot{q}(t)$ and $\ddot{q}(t)$ are the first and second time derivatives of $q(t)$ representing velocity and acceleration, respectively, - $F(t, q(t), \dot{q}(t))$ is the total force vector acting on the system. ### Forward Euler Method (Explicit) The Forward Euler method updates positions and velocities as follows: 1. **Update Acceleration**: \\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \] where $F$ is computed based on forces accumulated from all force fields. 2. **Update Velocity**: \\[ v^{n+1} = v^n + dt \cdot a^{n+1} \] 3. **Update Position**: \\[ q^{n+1} = q^n + dt \cdot v^{n+1} \] where $dt$ is the time step. ### Symplectic Euler Method (Semi-Implicit) The Symplectic Euler method updates positions and velocities as follows: 1. **Update Acceleration**: \\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \] 2. **Update Velocity**: \\[ v^{n+1} = v^n + dt \cdot a^{n+1} \] 3. **Update Position**: \\[ q^{n+1} = q^n + dt \cdot v^{n+1} \] but with the acceleration term updated first before applying velocity updates. In both methods, $M^{-1}$ is the inverse of the mass matrix, which can be diagonal for simplicity. If the mass matrix is not diagonal, a `LinearSolver` component must handle its inversion and application to the force vector. ### Key Features and Customization Options - **Symplectic Flag**: When set to `true`, it uses the Symplectic Euler method, which updates velocities before positions, providing better energy conservation for certain systems. The default is `true`, making it the semi-implicit variant by default. - **Thread Safety**: Controls thread safety in operations using the `threadSafeVisitor` flag (default: `false`). ### Detailed Workflow within the SOFA Framework 1. **Initialization and Setup**: - Initialization involves setting up the context, linear solver linkage (`l_linearSolver`), and reinitialization for correct setup. 2. **Force Computation**: - Computes forces by clearing the force vector and accumulating forces from all force fields. 3. **Acceleration Calculation**: - Calculates acceleration using $a = M^{-1}F$ if the mass matrix is diagonal or uses a linear solver for more complex cases. 4. **State Updates**: - Updates positions and velocities according to the chosen method (Forward Euler or Symplectic). 5. **Constraint Application**: - Projects constraints on forces and applies them to ensure physical validity, such as fixing certain degrees of freedom. 6. **System Matrix Assembly**: - Assembles system matrices if using a `LinearSolver` for more complex scenarios involving non-diagonal mass matrices. 7. **Solve Linear System**: - Solves the linear system to obtain solutions for positions and velocities. This comprehensive approach ensures that the EulerExplicitSolver component can handle both simple and complex simulations with appropriate numerical stability and physical accuracy.
{
  "name": "EulerExplicitSolver",
  "main": {
    "name": "EulerExplicitSolver",
    "namespace": "sofa::component::odesolver::forward",
    "module": "Sofa.Component.ODESolver.Forward",
    "include": "sofa/component/odesolver/forward/EulerExplicitSolver.h",
    "doc": "A simple explicit time integrator.\n\nThe simplest time integration.\nTwo variants of the Euler solver are available in this component:\n- forward Euler method, also called explicit Euler method\n- semi-implicit Euler method, also called semi-explicit Euler method or symplectic Euler\nIn both variants, acceleration is first computed. The system to compute the acceleration\nis M * a = f, where M is the mass matrix and f can be a force.\nIn case of a diagonal mass matrix, M is trivially invertible and the acceleration\ncan be computed without a linear solver.\nf is accumulated by force fields through the addForce function. Mappings can\nalso contribute by projecting forces of mapped objects.\nf is computed based on the current state (current velocity and position).\nExplicit Euler method:\nThe option \"symplectic\" must be set to false to use this variant.\nThe explicit Euler method produces an approximate discrete solution by iterating\nx_{n+1} = x_n + v_n * dt\nv_{n+1} = v_n + a * dt\nSemi-implicit Euler method:\nThe option \"symplectic\" must be set to true to use this variant.\nThe semi-implicit Euler method produces an approximate discrete solution by iterating\nv_{n+1} = v_n + a * dt\nx_{n+1} = x_n + v_{n+1} * dt\nThe semi-implicit Euler method is more robust than the standard Euler method.",
    "inherits": [
      "OdeSolver"
    ],
    "templates": [],
    "data_fields": [
      {
        "name": "d_symplectic",
        "type": "bool",
        "xmlname": "symplectic",
        "help": "If true (default), the velocities are updated before the positions and the method is symplectic, more robust. If false, the positions are updated before the velocities (standard Euler, less robust)."
      },
      {
        "name": "d_threadSafeVisitor",
        "type": "bool",
        "xmlname": "threadSafeVisitor",
        "help": "If true, do not use realloc and free visitors in fwdInteractionForceField."
      }
    ],
    "links": [
      {
        "name": "l_linearSolver",
        "target": "LinearSolver",
        "kind": "single",
        "xmlname": "linearSolver",
        "help": "Linear solver used by this component"
      }
    ],
    "methods": [
      {
        "name": "solve",
        "return_type": "void",
        "params": [
          {
            "name": "params",
            "type": "const core::ExecParams *"
          },
          {
            "name": "dt",
            "type": "SReal"
          },
          {
            "name": "xResult",
            "type": "sofa::core::MultiVecCoordId"
          },
          {
            "name": "vResult",
            "type": "sofa::core::MultiVecDerivId"
          }
        ],
        "is_virtual": true,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getIntegrationFactor",
        "return_type": "SReal",
        "params": [
          {
            "name": "inputDerivative",
            "type": "int"
          },
          {
            "name": "outputDerivative",
            "type": "int"
          }
        ],
        "is_virtual": true,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getSolutionIntegrationFactor",
        "return_type": "SReal",
        "params": [
          {
            "name": "outputDerivative",
            "type": "int"
          }
        ],
        "is_virtual": true,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "init",
        "return_type": "void",
        "params": [],
        "is_virtual": true,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "updateState",
        "return_type": "void",
        "params": [
          {
            "name": "vop",
            "type": "sofa::simulation::common::VectorOperations *"
          },
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "xResult",
            "type": "sofa::core::MultiVecCoordId"
          },
          {
            "name": "vResult",
            "type": "sofa::core::MultiVecDerivId"
          },
          {
            "name": "acc",
            "type": "const sofa::core::behavior::MultiVecDeriv &"
          },
          {
            "name": "dt",
            "type": "SReal"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "addSeparateGravity",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "dt",
            "type": "SReal"
          },
          {
            "name": "v",
            "type": "core::MultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": true,
        "access": "protected"
      },
      {
        "name": "computeForce",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "f",
            "type": "core::MultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": true,
        "access": "protected"
      },
      {
        "name": "computeAcceleration",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "acc",
            "type": "core::MultiVecDerivId"
          },
          {
            "name": "f",
            "type": "core::ConstMultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": true,
        "access": "protected"
      },
      {
        "name": "projectResponse",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "vecId",
            "type": "core::MultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": true,
        "access": "protected"
      },
      {
        "name": "solveConstraints",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          },
          {
            "name": "acc",
            "type": "core::MultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": true,
        "access": "protected"
      },
      {
        "name": "assembleSystemMatrix",
        "return_type": "void",
        "params": [
          {
            "name": "mop",
            "type": "sofa::simulation::common::MechanicalOperations *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "solveSystem",
        "return_type": "void",
        "params": [
          {
            "name": "solution",
            "type": "core::MultiVecDerivId"
          },
          {
            "name": "rhs",
            "type": "core::MultiVecDerivId"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      }
    ]
  },
  "desc": {
    "description": "The `EulerExplicitSolver` is an ODE (Ordinary Differential Equation) solver in the SOFA framework, designed for simple explicit time integration. This component provides two variants of Euler methods: **Forward Euler** and **Semi-Implicit Euler** (also known as Symplectic Euler). Both methods are used to solve motion equations by computing acceleration based on forces accumulated from force fields and mappings.\n\nThe key feature distinguishing these methods is the update order of velocities and positions. When `symplectic` is set to `true`, the semi-implicit method updates velocities before positions, which is more robust for certain scenarios. Conversely, setting `symplectic` to `false` uses the forward Euler method, updating positions first.\n\nThis solver interacts with other SOFA components through its API:\n- It inherits from `OdeSolver` and implements methods like `solve`, `getIntegrationFactor`, and `getSolutionIntegrationFactor`, which are critical for time integration.\n- A `LinearSolver` can be linked to handle more complex mass matrix scenarios, specifically when the mass matrix is not diagonal.\n\nData fields allow customization of behavior:\n- `symplectic`: Controls the update order (default: true).\n- `threadSafeVisitor`: Ensures thread safety during operations (default: false).\n\nThe solver uses a series of protected methods to compute forces, acceleration, and apply constraints. These methods collectively contribute to updating the mechanical state according to the chosen Euler method variant."
  },
  "maths": {
    "maths": "## Mathematical and Physical Description of the EulerExplicitSolver Component\n\nThe `EulerExplicitSolver` in the SOFA framework is designed for explicit time integration using two variants of the Euler method: **Forward Euler** (explicit) and **Symplectic Euler** (semi-implicit). These methods are widely used to solve ordinary differential equations (ODEs) arising from motion equations in physics-based simulations. The ODE system typically represents Newton's second law, which can be expressed as:\n\n\\[ m \\ddot{q}(t) = F(t, q(t), \\dot{q}(t)) \\]\n\nwhere:\n- $m$ is the mass matrix,\n- $q(t)$ are the generalized coordinates (position vector),\n- $\\dot{q}(t)$ and $\\ddot{q}(t)$ are the first and second time derivatives of $q(t)$ representing velocity and acceleration, respectively,\n- $F(t, q(t), \\dot{q}(t))$ is the total force vector acting on the system.\n\n### Forward Euler Method (Explicit)\n\nThe Forward Euler method updates positions and velocities as follows:\n1. **Update Acceleration**: \\\\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \\] where $F$ is computed based on forces accumulated from all force fields.\n2. **Update Velocity**: \\\\[ v^{n+1} = v^n + dt \\cdot a^{n+1} \\]\n3. **Update Position**: \\\\[ q^{n+1} = q^n + dt \\cdot v^{n+1} \\] where $dt$ is the time step.\n\n### Symplectic Euler Method (Semi-Implicit)\n\nThe Symplectic Euler method updates positions and velocities as follows:\n1. **Update Acceleration**: \\\\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \\]\n2. **Update Velocity**: \\\\[ v^{n+1} = v^n + dt \\cdot a^{n+1} \\]\n3. **Update Position**: \\\\[ q^{n+1} = q^n + dt \\cdot v^{n+1} \\] but with the acceleration term updated first before applying velocity updates.\n\nIn both methods, $M^{-1}$ is the inverse of the mass matrix, which can be diagonal for simplicity. If the mass matrix is not diagonal, a `LinearSolver` component must handle its inversion and application to the force vector.\n\n### Key Features and Customization Options\n- **Symplectic Flag**: When set to `true`, it uses the Symplectic Euler method, which updates velocities before positions, providing better energy conservation for certain systems. The default is `true`, making it the semi-implicit variant by default.\n- **Thread Safety**: Controls thread safety in operations using the `threadSafeVisitor` flag (default: `false`).\n\n### Detailed Workflow within the SOFA Framework\n1. **Initialization and Setup**:\n   - Initialization involves setting up the context, linear solver linkage (`l_linearSolver`), and reinitialization for correct setup.\n2. **Force Computation**:\n   - Computes forces by clearing the force vector and accumulating forces from all force fields.\n3. **Acceleration Calculation**:\n   - Calculates acceleration using $a = M^{-1}F$ if the mass matrix is diagonal or uses a linear solver for more complex cases.\n4. **State Updates**:\n   - Updates positions and velocities according to the chosen method (Forward Euler or Symplectic).\n5. **Constraint Application**:\n   - Projects constraints on forces and applies them to ensure physical validity, such as fixing certain degrees of freedom.\n6. **System Matrix Assembly**:\n   - Assembles system matrices if using a `LinearSolver` for more complex scenarios involving non-diagonal mass matrices.\n7. **Solve Linear System**:\n   - Solves the linear system to obtain solutions for positions and velocities.\n\nThis comprehensive approach ensures that the EulerExplicitSolver component can handle both simple and complex simulations with appropriate numerical stability and physical accuracy."
  },
  "summary": {
    "abstract": "The `EulerExplicitSolver` implements explicit time integration using Forward Euler or Symplectic Euler methods to update positions and velocities based on computed accelerations from forces.",
    "sheet": "\n# EulerExplicitSolver\n\n## Overview\nThe `EulerExplicitSolver` is an ODE solver in the SOFA framework that provides two variants of the Euler method: **Forward Euler** (explicit) and **Symplectic Euler** (semi-implicit). It handles time integration by updating positions and velocities based on computed accelerations from forces. The component inherits from `OdeSolver` and can be linked with a `LinearSolver` for more complex mass matrix scenarios.\n\n## Mathematical Model\nThe `EulerExplicitSolver` implements the following methods:\n\n### Forward Euler Method (Explicit)\n1. **Update Acceleration**: \\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \\]\n2. **Update Velocity**: \\[ v^{n+1} = v^n + dt \times a^{n+1} \\]\n3. **Update Position**: \\[ q^{n+1} = q^n + dt \times v^{n+1} \\]\n\n### Symplectic Euler Method (Semi-Implicit)\n1. **Update Acceleration**: \\[ a^{n+1} = M^{-1} F(t^n, q^n, v^n) \\]\n2. **Update Velocity**: \\[ v^{n+1} = v^n + dt \times a^{n+1} \\]\n3. **Update Position**: \\[ q^{n+1} = q^n + dt \times v^{n+1} \\]\n\nIn both methods, $M^{-1}$ is the inverse of the mass matrix, which can be diagonal for simplicity. If the mass matrix is not diagonal, a `LinearSolver` component must handle its inversion and application to the force vector.\n\n## Parameters and Data\n- **symplectic**: Controls the update order (default: true). When set to `true`, it uses the Symplectic Euler method; otherwise, it uses the Forward Euler method.\n- **threadSafeVisitor**: Ensures thread safety during operations (default: false).\n\n## Dependencies and Connections\nThe component typically requires a `LinearSolver` if the mass matrix is not diagonal. It interacts with force fields to accumulate forces and mappings to project forces of mapped objects."
  }
}