PolynomialSpringsForceField
This component belongs to the category of ForceField. This component allows to simulate springs with Polynomial stress strain behavior. If we note:
the spring force
the cross section (always 1.0)
the stress-strain non-linear function
the original length and
the current length of the spring
the point displacement
the generic non-linear force can thus be written:
where
is polynom as follows:
and
The dedication of jacobian matrix for PolynomialSpringForceField is given below:
Note that a RestShapePolynomialSpringsForceField does exist. It will compute the same non-linear force with regards to the rest shape of one single object. To avoid Nan problems when a spring has a zero length, an exponential addition to the denominator has been added. As a result, the stress simulation is shifted compared with polynomial values, but it keeps its nonlinearity:
More details were given in the pull-request #1342.
Data
The polynomial parameters are set as two arrays:
- polynomialDegree: describing the set of polynomial degrees for every spring
- polynomialStiffness: describing the set of polynomial coefficients sequentially combined in one vector.
The coefficients are put from smaller degree to bigger one, and the free coefficient is always zero (since for no strain we have no stress). For examples the coefficients for polynomials [3,2,4] will be put as [a1,a2,a3,b1,b2,c1,c2,c3,c4].
- firstObjectPoints corresponding to the indices of the points related to the first object
- secondObjectPoints corresponding to the indices of the points related to the second object
- compressible: indicating if object compresses without reaction force
Usage
The PolynomialSpringsForceField requires two different objects to link, which means two MechanicalObjects on which the non-linear spring will act. On the other hand, RestShapePolynomialSpringsForceField will act on one single body, i.e. one MechanicalObject.
Example
This component is used as follows in XML format:
or using Python:
An example scene involving a PolynomialSpringsForceField is available in examples/Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn
Target: Sofa.Component.SolidMechanics.Spring
namespace: sofa::component::solidmechanics::spring
parents:
PairInteractionForceField
Data:
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the objet belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
isCompliance | Consider the component as a compliance, else as a stiffness | 0 |
rayleighStiffness | Rayleigh damping - stiffness matrix coefficient | 0 |
firstObjectPoints | points related to the first object | |
secondObjectPoints | points related to the second object | |
polynomialStiffness | coefficients for all spring polynomials | |
polynomialDegree | vector of values that show polynomials degrees | |
computeZeroLength | flag to compute initial length for springs | 1 |
zeroLength | initial length for springs | |
recompute_indices | Recompute indices (should be false for BBOX) | 0 |
compressible | Indicates if object compresses without reactio force | 0 |
springColor | spring color | 0 1 0 1 |
Visualization | ||
drawMode | The way springs will be drawn: - 0: Line - 1:Cylinder - 2: Arrow | 0 |
showArrowSize | size of the axis | 0.01 |
showIndicesScale | Scale for indices display. (default=0.02) | 0.02 |
Links:
Name | Description |
---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) |
slaves | Sub-objects used internally by this object |
master | nullptr for regular objects, or master object for which this object is one sub-objects |
mechanicalStates | List of mechanical states to which this component is associated |
object1 | First object associated to this component |
object2 | Second object associated to this component |
Examples
Component/SolidMechanics/Spring/PolynomialSpringsForceField.scn
<?xml version="1.0" ?>
<Node name="lroot" gravity="0 0 0" dt="0.02">
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin name="Sofa.Component.IO.Mesh"/> <!-- Needed to use components [MeshGmshLoader MeshOBJLoader] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [BarycentricMapping] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TetrahedralCorotationalFEMForceField] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.Spring"/> <!-- Needed to use components [PolynomialSpringsForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TetrahedronSetGeometryAlgorithms TetrahedronSetTopologyContainer] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
<VisualStyle displayFlags="showInteractionForceFields"/>
<DefaultAnimationLoop/>
<MeshOBJLoader name="LiverSurface" filename="mesh/liver-smooth.obj" />
<Node name="Liver" >
<EulerImplicitSolver name="cg_odesolver" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver name="linear solver" iterations="25" tolerance="1e-09" threshold="1e-09" />
<MeshGmshLoader name="meshLoader" filename="mesh/liver.msh" />
<TetrahedronSetTopologyContainer name="topo" src="@meshLoader" />
<MechanicalObject name="dofs" src="@meshLoader" />
<TetrahedronSetGeometryAlgorithms template="Vec3" name="GeomAlgo" />
<DiagonalMass name="computed using mass density" massDensity="1" />
<TetrahedralCorotationalFEMForceField template="Vec3" name="FEM" method="large" poissonRatio="0.3" youngModulus="3000" computeGlobalMatrix="0" />
<FixedProjectiveConstraint name="FixedProjectiveConstraint" indices="3 39 64" />
<Node name="Visu" tags="Visual" gravity="0 -9.81 0">
<OglModel name="VisualModel" src="@../../LiverSurface" />
<BarycentricMapping name="visual mapping" input="@../dofs" output="@VisualModel" />
</Node>
<Node name="Weight" >
<MechanicalObject template="Vec3" name="myParticle" rest_position="0 0 0" position="0 0 0" />
<UniformMass totalMass="30" />
<PolynomialSpringsForceField polynomialDegree="3" polynomialStiffness="20 10 50" object1='@.' firstObjectPoints='0' object2='@../dofs' secondObjectPoints='15' drawMode='0' showIndicesScale="1"/>
</Node>
</Node>
</Node>
def createScene(rootNode):
lroot = rootNode.addChild('lroot', gravity="0 0 0", dt="0.02")
lroot.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
lroot.addObject('RequiredPlugin', name="Sofa.Component.IO.Mesh")
lroot.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
lroot.addObject('RequiredPlugin', name="Sofa.Component.Mapping.Linear")
lroot.addObject('RequiredPlugin', name="Sofa.Component.Mass")
lroot.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
lroot.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic")
lroot.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.Spring")
lroot.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
lroot.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Dynamic")
lroot.addObject('RequiredPlugin', name="Sofa.Component.Visual")
lroot.addObject('RequiredPlugin', name="Sofa.GL.Component.Rendering3D")
lroot.addObject('VisualStyle', displayFlags="showInteractionForceFields")
lroot.addObject('DefaultAnimationLoop')
lroot.addObject('MeshOBJLoader', name="LiverSurface", filename="mesh/liver-smooth.obj")
Liver = lroot.addChild('Liver')
Liver.addObject('EulerImplicitSolver', name="cg_odesolver", rayleighStiffness="0.1", rayleighMass="0.1")
Liver.addObject('CGLinearSolver', name="linear solver", iterations="25", tolerance="1e-09", threshold="1e-09")
Liver.addObject('MeshGmshLoader', name="meshLoader", filename="mesh/liver.msh")
Liver.addObject('TetrahedronSetTopologyContainer', name="topo", src="@meshLoader")
Liver.addObject('MechanicalObject', name="dofs", src="@meshLoader")
Liver.addObject('TetrahedronSetGeometryAlgorithms', template="Vec3", name="GeomAlgo")
Liver.addObject('DiagonalMass', name="computed using mass density", massDensity="1")
Liver.addObject('TetrahedralCorotationalFEMForceField', template="Vec3", name="FEM", method="large", poissonRatio="0.3", youngModulus="3000", computeGlobalMatrix="0")
Liver.addObject('FixedProjectiveConstraint', name="FixedProjectiveConstraint", indices="3 39 64")
Visu = Liver.addChild('Visu', tags="Visual", gravity="0 -9.81 0")
Visu.addObject('OglModel', name="VisualModel", src="@../../LiverSurface")
Visu.addObject('BarycentricMapping', name="visual mapping", input="@../dofs", output="@VisualModel")
Weight = Liver.addChild('Weight')
Weight.addObject('MechanicalObject', template="Vec3", name="myParticle", rest_position="0 0 0", position="0 0 0")
Weight.addObject('UniformMass', totalMass="30")
Weight.addObject('PolynomialSpringsForceField', polynomialDegree="3", polynomialStiffness="20 10 50", object1="@.", firstObjectPoints="0", object2="@../dofs", secondObjectPoints="15", drawMode="0", showIndicesScale="1")