TaitSurfacePressureForceField
This component computes the volume enclosed by a surface mesh and apply a pressure force following Tait's equation: \(P = P_0 - B((V/V_0)^\gamma - 1)\). This ForceField can be used to apply : * a constant pressure (set \(B=0\) and use \(P_0\)) * an ideal gas pressure (set \(\gamma=1\) and use \(B\)) * a pressure from water (set \(\gamma=7\) and use \(B\))
Vec3d
Templates:
- Vec3d
Target: Sofa.Component.MechanicalLoad
namespace: sofa::component::mechanicalload
parents:
- ForceField
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object 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 |
rayleighStiffness | Rayleigh damping - stiffness matrix coefficient | 0 |
pressureTriangles | OUT: list of triangles where a pressure is applied (mesh triangles + tessellated quads) | |
Controls | ||
p0 | IN: Rest pressure when V = V0 | 0 |
B | IN: Bulk modulus (resistance to uniform compression) | 0 |
gamma | IN: Bulk modulus (resistance to uniform compression) | 0 |
injectedVolume | IN: Injected (or extracted) volume since the start of the simulation | 0 |
maxInjectionRate | IN: Maximum injection rate (volume per second) | 1000 |
Results | ||
initialVolume | OUT: Initial volume, as computed from the surface rest position | 0 |
currentInjectedVolume | OUT: Current injected (or extracted) volume (taking into account maxInjectionRate) | 0 |
v0 | OUT: Rest volume (as computed from initialVolume + injectedVolume) | 0 |
currentVolume | OUT: Current volume, as computed from the last surface position | 0 |
currentPressure | OUT: Current pressure, as computed from the last surface position | 0 |
currentStiffness | OUT: dP/dV at current volume and pressure | 0 |
volumeAfterTC | OUT: Volume after a topology change | |
surfaceAreaAfterTC | OUT: Surface area after a topology change | 0 |
Stats | ||
initialSurfaceArea | OUT: Initial surface area, as computed from the surface rest position | 0 |
currentSurfaceArea | OUT: Current surface area, as computed from the last surface position | 0 |
Visualization | ||
drawForceScale | DEBUG: scale used to render force vectors | 0.001 |
drawForceColor | DEBUG: color used to render force vectors | 0 1 1 1 |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
mstate | MechanicalState used by this component | MechanicalState<Vec3d> |
topology | link to the topology container | BaseMeshTopology |
Examples
TaitSurfacePressureForceField.scn
<Node name="root" dt="0.02" gravity = "0 0 0">
<RequiredPlugin name="Sofa.Component.Collision.Detection.Algorithm"/> <!-- Needed to use components [BVHNarrowPhase BruteForceBroadPhase CollisionPipeline] -->
<RequiredPlugin name="Sofa.Component.Collision.Detection.Intersection"/> <!-- Needed to use components [DiscreteIntersection] -->
<RequiredPlugin name="Sofa.Component.Collision.Geometry"/> <!-- Needed to use components [TriangleCollisionModel] -->
<RequiredPlugin name="Sofa.Component.Collision.Response.Contact"/> <!-- Needed to use components [CollisionResponse] -->
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin name="Sofa.Component.IO.Mesh"/> <!-- Needed to use components [MeshOBJLoader] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [IdentityMapping] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [DiagonalMass] -->
<RequiredPlugin name="Sofa.Component.MechanicalLoad"/> <!-- Needed to use components [TaitSurfacePressureForceField] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TriangularFEMForceFieldOptim] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.Spring"/> <!-- Needed to use components [FastTriangularBendingSprings] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [TriangleSetGeometryAlgorithms TriangleSetTopologyContainer TriangleSetTopologyModifier] -->
<RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
<DefaultAnimationLoop/>
<CollisionPipeline verbose="0" />
<BruteForceBroadPhase/>
<BVHNarrowPhase/>
<CollisionResponse response="PenalityContactForceField" />
<DiscreteIntersection />
<Node name="sphere">
<EulerImplicitSolver name="cg_odesolver" rayleighMass="0.1" rayleighStiffness="0.2" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MeshOBJLoader name="loader" filename="mesh/sphere_02b.obj" scale="0.25 0.25 0.25" rotation="-90 0 0" triangulate="1" />
<TriangleSetTopologyContainer src="@loader" />
<MechanicalObject src="@loader" template="Vec3" name="DOFs" />
<TriangleSetTopologyModifier />
<TriangleSetGeometryAlgorithms />
<BoxConstraint box="-10 -10 -10 10 -5 10" />
<TriangularFEMForceFieldOptim name="FEM" youngModulus="10000" poissonRatio="0.4" restScale="0.97" method="large" />
<FastTriangularBendingSprings name="Bending" bendingStiffness="100" />
<TaitSurfacePressureForceField name="Pressure" gamma="5" B="10000" injectedVolume="100" printLog="1" />
<DiagonalMass name="mass" massDensity="1" printLog="0" />
<TriangleCollisionModel name="CM" />
<Node name="Visu">
<OglModel name="VisualModel" src="@../loader" color="white" />
<IdentityMapping />
</Node>
</Node>
</Node>
def createScene(root_node):
root = root_node.addChild('root', dt="0.02", gravity="0 0 0")
root.addObject('RequiredPlugin', name="Sofa.Component.Collision.Detection.Algorithm")
root.addObject('RequiredPlugin', name="Sofa.Component.Collision.Detection.Intersection")
root.addObject('RequiredPlugin', name="Sofa.Component.Collision.Geometry")
root.addObject('RequiredPlugin', name="Sofa.Component.Collision.Response.Contact")
root.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
root.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select")
root.addObject('RequiredPlugin', name="Sofa.Component.IO.Mesh")
root.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
root.addObject('RequiredPlugin', name="Sofa.Component.Mapping.Linear")
root.addObject('RequiredPlugin', name="Sofa.Component.Mass")
root.addObject('RequiredPlugin', name="Sofa.Component.MechanicalLoad")
root.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
root.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic")
root.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.Spring")
root.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Dynamic")
root.addObject('RequiredPlugin', name="Sofa.GL.Component.Rendering3D")
root.addObject('DefaultAnimationLoop', )
root.addObject('CollisionPipeline', verbose="0")
root.addObject('BruteForceBroadPhase', )
root.addObject('BVHNarrowPhase', )
root.addObject('CollisionResponse', response="PenalityContactForceField")
root.addObject('DiscreteIntersection', )
sphere = root.addChild('sphere')
sphere.addObject('EulerImplicitSolver', name="cg_odesolver", rayleighMass="0.1", rayleighStiffness="0.2", printLog="false")
sphere.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
sphere.addObject('MeshOBJLoader', name="loader", filename="mesh/sphere_02b.obj", scale="0.25 0.25 0.25", rotation="-90 0 0", triangulate="1")
sphere.addObject('TriangleSetTopologyContainer', src="@loader")
sphere.addObject('MechanicalObject', src="@loader", template="Vec3", name="DOFs")
sphere.addObject('TriangleSetTopologyModifier', )
sphere.addObject('TriangleSetGeometryAlgorithms', )
sphere.addObject('BoxConstraint', box="-10 -10 -10 10 -5 10")
sphere.addObject('TriangularFEMForceFieldOptim', name="FEM", youngModulus="10000", poissonRatio="0.4", restScale="0.97", method="large")
sphere.addObject('FastTriangularBendingSprings', name="Bending", bendingStiffness="100")
sphere.addObject('TaitSurfacePressureForceField', name="Pressure", gamma="5", B="10000", injectedVolume="100", printLog="1")
sphere.addObject('DiagonalMass', name="mass", massDensity="1", printLog="0")
sphere.addObject('TriangleCollisionModel', name="CM")
visu = sphere.addChild('Visu')
visu.addObject('OglModel', name="VisualModel", src="@../loader", color="white")
visu.addObject('IdentityMapping', )