Skip to content

Commit

Permalink
Merge pull request #151 from hugtalbot/202408_final_cleaning_doc
Browse files Browse the repository at this point in the history
Final cleaning for the doc
  • Loading branch information
hugtalbot authored Aug 9, 2024
2 parents 1e94cf2 + 64319ce commit 1701969
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 25 deletions.
2 changes: 1 addition & 1 deletion 20_Simulation_Principles/30_Topology.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ All MeshLoaders share a common API, especially several available data:
* _**createSubelements**_: to divide all n-D elements into their (n-1)-D boundary elements (e.g. tetrahedra to triangles)
* _**onlyAttachedPoints**_: to keep only points attached to elements of the mesh

Additional data (*translation*, *rotation* and *scale3d*) are available but it rather advised to use a [TransformEngine](../../components/engines/transform/transformengine/) to apply a transformation to your geometry.
Additional data (*translation*, *rotation* and *scale3d*) are available but it rather advised to use a [TransformEngine](../../components/engine/transform/transformengine/) to apply a transformation to your geometry.

All MeshLoaders propose several data as output (for the most used):
* _**position**_: vector of vertices of the mesh loaded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ ForceField implementations
See examples of ForceField implementation:

- [ConstantForceField](../../../components/mechanicalload/constantforcefield/)
- [TetrahedronFEMForceField](../../../components/solidmechanics/fem/elasticity/tetrahedronfemforcefield/)
- [TetrahedronFEMForceField](../../../components/solidmechanics/fem/elastic/tetrahedronfemforcefield/)



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,34 @@ In SOFA, the collision detection takes as input the collision models (geometric
This contact information is passed to the contact manager, which creates contact interactions of various types based on customizable rules.

Given $n$ moving objects in a virtual environment, testing all objects pairs tend to perform $n^2$ pairwise checks.
When $ \mathcal{O }(n^2)$ complexity, the collision detection is usually divided into two successive steps:
When $\mathcal{O}(n^2)$ complexity, the collision detection is usually divided into two successive steps:

- a [broad phase](../../../components/components/collision/detection/algorithm/broadphase/)
- a [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase)
- a [broad phase](../../../components/collision/detection/algorithm/broadphase/)
- a [narrow phase](../../../components/collision/detection/algorithm/narrowphase)

Several [broad phase](../../../components/components/collision/detection/algorithm/broadphase/) and [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase) methods are available in SOFA.
Several [broad phase](../../../components/collision/detection/algorithm/broadphase/) and [narrow phase](../../../components/collision/detection/algorithm/narrowphase) methods are available in SOFA.
All of these methods will compute the contact points between collision models. The evaluation of these contacts will be done using Intersection Methods. Here again, various [intersection methods](../../../components/collision/detection/intersection/intersectionmethod/) are available in SOFA. The choice of the collision detection method and the intersection method depends on your specific simulation use case.

All collision detection algorithms are available in *components/collision/detection/algorithm*, see for instance the [BruteForceBroadPhase](../../../components/collision/detection/algorithm/bruteforcebroadphase/).


### Broad phase

The first step of the pipeline is the so-called [broad-phase](../../../components/components/collision/detection/algorithm/broadphase/). It aims at quickly and efficiently removing objects pairs that are not in collision.
The first step of the pipeline is the so-called [broad-phase](../../../components/collision/detection/algorithm/broadphase/). It aims at quickly and efficiently removing objects pairs that are not in collision.

The broad phase uses a set of root collision models in order to compute potentially colliding pairs. It can for instance rely on the bounding boxes of each object with a collision model, thus efficiently checking whether boxes collide or not. This step does not state if pairs of objects collide, but it detects if they *potentially* collide. As output, the broad phase returns pairs of potentially colliding collision models.


### Narrow phase: detect intersection

The [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase) of detection can rely on collision models to detect a contact. Note that different collision models are available to detect a contact:
The [narrow phase](../../../components/collision/detection/algorithm/narrowphase) of detection can rely on collision models to detect a contact. Note that different collision models are available to detect a contact:

- using [primitives](../../../components/collision/geometry/collisionmodels/) (mostly used): point, line, triangle, sphere, cube, cylinder or oriented bounding boxes (OBB)
- using distance grid, associated to each object in the scene
- using ray casting: that send rays in the volume of simulation to compute a volume of intersection


All collision detection methods will rely on intersection methods during the broad and/or [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase) in order to assess if the models do collide. Given 2 collision elements, these intersection methods test if an intersection is possible.
All collision detection methods will rely on intersection methods during the broad and/or [narrow phase](../../../components/collision/detection/algorithm/narrowphase) in order to assess if the models do collide. Given 2 collision elements, these intersection methods test if an intersection is possible.

In SOFA, a proximity method can be used to detect contact when two objects are getting closer to another. Evaluating this proximity allows for a better anticipation of the contact, i.e. more stable contact. The two main implementations in SOFA are:

Expand All @@ -73,7 +73,7 @@ Discrete intersection methods also exist to compute intersection only if models
Output of the detection
-----------------------

As output, the collision detection (further to the [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase)) returns pairs of geometric primitives with the corresponding collision points. The collision information is saved in a vector of DetectionOutput. This data structure is a generic description of a contact point, used for most collision models except special cases such as GPU-based collisions.
As output, the collision detection (further to the [narrow phase](../../../components/collision/detection/algorithm/narrowphase)) returns pairs of geometric primitives with the corresponding collision points. The collision information is saved in a vector of DetectionOutput. This data structure is a generic description of a contact point, used for most collision models except special cases such as GPU-based collisions.

Each contact point is described by a DetectionOutput made up of:

Expand All @@ -90,7 +90,7 @@ Collision response
------------------

The step of collision response is triggered in the [CollisionPipeline](../../../components/collision/detection/algorithm/collisionpipeline/).
The colliding models returned by the [narrow phase](../../../components/components/collision/detection/algorithm/narrowphase) are finally given to the ContactManager, which creates contact interactions of various types based on customizable rules. You can specify which one you want to use in the DefaultContactManager. Response has been implemented based on:
The colliding models returned by the [narrow phase](../../../components/collision/detection/algorithm/narrowphase) are finally given to the ContactManager, which creates contact interactions of various types based on customizable rules. You can specify which one you want to use in the DefaultContactManager. Response has been implemented based on:

- the penalty method, efficient but subject to instability if not properly tuned
- the persistent method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Typical mappings compute the correspondence between different geometrical models

One can define two representations of an object, both using a different topology:

- one mechanical model with its degrees of freedom $$q$$
- one collision model with its degrees of freedom $$p$$
- one mechanical model with its degrees of freedom $q$
- one collision model with its degrees of freedom $p$

![Application of mappings](https://www.sofa-framework.org/wp-content/uploads/2018/10/Mapping-illustration.png)

Expand Down Expand Up @@ -64,13 +64,20 @@ applyDJT(const MechanicalParams*, MultiVecDerivId parentForce, ConstMultiVecDeri
applyJT(const ConstraintParams*, MultiMatrixDerivId inConst, ConstMultiMatrixDerivId outConst );
```

Common mappings
---------------
- [IdentityMapping](../../../components/mapping/linear/identitymapping/) when both models have the same degrees of freedom
- [BarycentricMapping](../../../components/mapping/linear/barycentricmapping/) interpolating degrees of freedom using barycentric coordinates
- [RigidMapping](../../../components/mapping/nonlinear/rigidmapping/) used with RigidObject


Topological mapping
-------------------

Topological mappings are an additional type of mappings making the correspondence between hierarchical topologies. You can thus find :

- a _Hexa2TetraTopologicalMapping_: computing the correspondence between a hexahedral and a tetrahedral topology, by dividing each hexahedron into 6 tetrahedra
- a _Hexa2QuadTopologicalMapping_: computing the correspondence between a hexahedral topology and its surface quadrangular topology
- a _Tetra2TriangleTopologicalMapping_: computing the correspondence between a tetrahedral topology and its surface triangular topology
- a _Quad2TriangleTopologicalMapping_: computing the correspondence between a quadrangular and a triangular topology, by dividing each quad into 2 triangles
- a _Triangle2EdgeTopologicalMapping_: computing the correspondence between a triangular and an edge topology
- a [Hexa2TetraTopologicalMapping](../../../components/topology/mapping/hexa2tetratopologicalmapping/): computing the correspondence between a hexahedral and a tetrahedral topology, by dividing each hexahedron into 6 tetrahedra
- a [Hexa2QuadTopologicalMapping](../../../components/topology/mapping/hexa2quadtopologicalmapping/): computing the correspondence between a hexahedral topology and its surface quadrangular topology
- a [Tetra2TriangleTopologicalMapping](../../../components/topology/mapping/tetra2triangletopologicalmapping/): computing the correspondence between a tetrahedral topology and its surface triangular topology
- a [Quad2TriangleTopologicalMapping](../../../components/topology/mapping/quad2triangletopologicalmapping/): computing the correspondence between a quadrangular and a triangular topology, by dividing each quad into 2 triangles
- a [Triangle2EdgeTopologicalMapping](../../../components/topology/mapping/triangle2edgetopologicalmapping/): computing the correspondence between a triangular and an edge topology
14 changes: 7 additions & 7 deletions 20_Simulation_Principles/60_Constraint/20_Lagrange_Constraint.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,13 @@ ConstraintCorrection

As explained above, a _ConstraintCorrection_ is required in the simulation to define the way the compliance matrix $\mathbf{W}$ is computed. Different classes of _ConstraintCorrection_ exist in SOFA corresponding to different approaches:

- _[UncoupledConstraintCorrection](../../../components/constraint/lagrangian/correction/uncoupledconstraintcorrection/)_: makes the approximation that the compliance matrix $\mathbf{W}$ is diagonal. This is as strong assumption since a diagonal matrix means that all constraints are independent from each other. Note that you can directly specify the compliance matrix values within the Data field "compliance"
- [UncoupledConstraintCorrection](../../../components/constraint/lagrangian/correction/uncoupledconstraintcorrection/): makes the approximation that the compliance matrix $\mathbf{W}$ is diagonal. This is as strong assumption since a diagonal matrix means that all constraints are independent from each other. Note that you can directly specify the compliance matrix values within the Data field "compliance"

- _LinearSolverConstraintCorrection_: computes the compliance matrix $\mathbf{W}=\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ where $\mathbf{A}^{-1}$ comes from a direct solver associated to the object. Since the direct solvers in SOFA factorize the matrix $\mathbf{A}$ (for instance using a LDL factorization if you use the _LDLSolver_), the factorization is reused to compute the compliance matrix. The matrix-matrix multiplication $\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ is not possible in case of a matrix-free solver, since the assembled inverse matrix $\mathbf{A}^{-1}$ is not available. From the factorization of $\mathbf{A}$, the computation of $\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ done in the function _addJMInvJt()_ requires to call the _solve()_ function from the direct solver, computing a matrix-vector multiplication, for each line of the constraint matrix $\mathbf{H}$, i.e. for each constraint. This approach can therefore be very computationally-demanding if you have many constraints. Note that this ConstraintCorrection proposes an optimization for wire-like structures (boolean option)
- [LinearSolverConstraintCorrection](../../../components/constraint/lagrangian/correction/linearsolverconstraintcorrection/): computes the compliance matrix $\mathbf{W}=\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ where $\mathbf{A}^{-1}$ comes from a direct solver associated to the object. Since the direct solvers in SOFA factorize the matrix $\mathbf{A}$ (for instance using a LDL factorization if you use the _LDLSolver_), the factorization is reused to compute the compliance matrix. The matrix-matrix multiplication $\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ is not possible in case of a matrix-free solver, since the assembled inverse matrix $\mathbf{A}^{-1}$ is not available. From the factorization of $\mathbf{A}$, the computation of $\mathbf{H}\mathbf{A}^{-1}\mathbf{H}^T$ done in the function _addJMInvJt()_ requires to call the _solve()_ function from the direct solver, computing a matrix-vector multiplication, for each line of the constraint matrix $\mathbf{H}$, i.e. for each constraint. This approach can therefore be very computationally-demanding if you have many constraints. Note that this ConstraintCorrection proposes an optimization for wire-like structures (boolean option)

- _PrecomputedConstraintCorrection_: instead of computing $\mathbf{A}^{-1}$ at each time step, this constraint correction precomputes once the inverse of $\mathbf{A}$ at the initialization of the simulation and stores this matrix into a file. This speeds up the simulation but it can lead to a lack of accuracy in case the system matrix $\mathbf{A}$ changes during the simulation
- [PrecomputedConstraintCorrection](../../../components/constraint/lagrangian/correction/precomputedconstraintcorrection/): instead of computing $\mathbf{A}^{-1}$ at each time step, this constraint correction precomputes once the inverse of $\mathbf{A}$ at the initialization of the simulation and stores this matrix into a file. This speeds up the simulation but it can lead to a lack of accuracy in case the system matrix $\mathbf{A}$ changes during the simulation

- _GenericConstraintCorrection_: similar to the _LinearSolverConstraintCorrection_, it allows to declare only once all the direct solvers (one for each constraint object) used to compute the global $\mathbf{W}$, whereas the previously described constraint correction needs to be added for each object
- [GenericConstraintCorrection](../../../components/constraint/lagrangian/correction/genericconstraintcorrection/): similar to the _LinearSolverConstraintCorrection_, it allows to declare only once all the direct solvers (one for each constraint object) used to compute the global $\mathbf{W}$, whereas the previously described constraint correction needs to be added for each object



Expand All @@ -219,11 +219,11 @@ Constraint laws

In SOFA, you can find several of interaction constraint laws available to include in your simulation. A lot of them is available in the SofaConstraint module, among them:

- _UnilateralInteractionConstraint_: constraint of inequality (like the $\Psi$ function described above in the [Constraint problem](#constraint-problem) section), that fits for instance contact and collision cases
- [UnilateralLagrangianConstraint](../../../components/constraint/lagrangian/model/unilaterallagrangianconstraint/): constraint of inequality (like the $\Psi$ function described above in the [Constraint problem](#constraint-problem) section), that fits for instance contact and collision cases

- _BilateralInteractionConstraint_: constraint of equality (like the $\Phi$ function described above in the [Constraint problem](#constraint-problem) section), that fits for instance interactions, attachments between two paired objects
- [BilateralLagrangianConstraint](../../../components/constraint/lagrangian/model/bilaterallagrangianconstraint/): constraint of equality (like the $\Phi$ function described above in the [Constraint problem](#constraint-problem) section), that fits for instance interactions, attachments between two paired objects

- _SlidingConstraint_: constraint in equality, like the _BilateralInteractionConstraint_, but only active for some vectors of the physics space (for instance only the x-direction)
- [SlidingLagrangianConstraint](../../../components/constraint/lagrangian/model/slidinglagrangianconstraint/): constraint in equality, like the _BilateralInteractionConstraint_, but only active for some vectors of the physics space (for instance only the x-direction)

Classes defining constraints between a pair of objects inherit from the class _PairInteractionConstraint_. The associated API functions are:

Expand Down

0 comments on commit 1701969

Please sign in to comment.