From 64319ce64aad8f61568ad0cb5183c452a43f003e Mon Sep 17 00:00:00 2001 From: Hugo Talbot Date: Fri, 9 Aug 2024 17:49:11 +0200 Subject: [PATCH] Final cleaning for the doc --- 20_Simulation_Principles/30_Topology.md | 2 +- .../12_ForceField.md | 2 +- .../20_Collision.md | 18 ++++++++-------- .../40_Mapping.md | 21 ++++++++++++------- .../60_Constraint/20_Lagrange_Constraint.md | 14 ++++++------- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/20_Simulation_Principles/30_Topology.md b/20_Simulation_Principles/30_Topology.md index 98f8da0fa..20b0fb466 100644 --- a/20_Simulation_Principles/30_Topology.md +++ b/20_Simulation_Principles/30_Topology.md @@ -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 diff --git a/20_Simulation_Principles/50_Multi-Model_Representation/12_ForceField.md b/20_Simulation_Principles/50_Multi-Model_Representation/12_ForceField.md index d5256615e..e10c6d56e 100644 --- a/20_Simulation_Principles/50_Multi-Model_Representation/12_ForceField.md +++ b/20_Simulation_Principles/50_Multi-Model_Representation/12_ForceField.md @@ -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/) diff --git a/20_Simulation_Principles/50_Multi-Model_Representation/20_Collision.md b/20_Simulation_Principles/50_Multi-Model_Representation/20_Collision.md index 645a7fc1d..c62ee8702 100644 --- a/20_Simulation_Principles/50_Multi-Model_Representation/20_Collision.md +++ b/20_Simulation_Principles/50_Multi-Model_Representation/20_Collision.md @@ -32,12 +32,12 @@ 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/). @@ -45,21 +45,21 @@ All collision detection algorithms are available in *components/collision/detect ### 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: @@ -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: @@ -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 diff --git a/20_Simulation_Principles/50_Multi-Model_Representation/40_Mapping.md b/20_Simulation_Principles/50_Multi-Model_Representation/40_Mapping.md index 82479f34a..e56c4ecc9 100644 --- a/20_Simulation_Principles/50_Multi-Model_Representation/40_Mapping.md +++ b/20_Simulation_Principles/50_Multi-Model_Representation/40_Mapping.md @@ -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) @@ -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 diff --git a/20_Simulation_Principles/60_Constraint/20_Lagrange_Constraint.md b/20_Simulation_Principles/60_Constraint/20_Lagrange_Constraint.md index 7d9e27b60..f12c05ceb 100644 --- a/20_Simulation_Principles/60_Constraint/20_Lagrange_Constraint.md +++ b/20_Simulation_Principles/60_Constraint/20_Lagrange_Constraint.md @@ -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 @@ -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: