Skip to content

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
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', )