Skip to content

Commit

Permalink
Merge pull request #135 from SofaDefrost/addBouncingBallExample
Browse files Browse the repository at this point in the history
Add bouncing ball example
  • Loading branch information
olivier-goury authored Aug 27, 2024
2 parents f5a5872 + 4a1469d commit c43fe21
Show file tree
Hide file tree
Showing 8 changed files with 6,552 additions and 0 deletions.
20 changes: 20 additions & 0 deletions examples/bouncingBall/RID.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
19 1
5
7
40
45
57
71
93
94
178
204
216
235
240
364
396
570
593
692
699
685 changes: 685 additions & 0 deletions examples/bouncingBall/modes.txt

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions examples/bouncingBall/softSphereFalling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Sofa
import Sofa.Core
import os
pathSceneFile = os.path.dirname(os.path.abspath(__file__))
pathMesh = os.path.dirname(os.path.abspath(__file__))+'/'
# Units: mm, kg, s. Pressure in kPa = k (kg/(m.s^2)) = k (g/(mm.s^2) = kg/(mm.s^2)

def createScene(rootNode):
rootNode.addObject('VisualStyle', displayFlags='showVisualModels hideBehaviorModels showCollisionModels hideBoundingCollisionModels showForceFields showInteractionForceFields hideWireframe')
rootNode.gravity=[0,-9810, 0]
rootNode.dt = 0.0001
rootNode.addObject('FreeMotionAnimationLoop')
rootNode.addObject('GenericConstraintSolver', name='GSSolver', maxIterations='10000', tolerance='1e-15')
rootNode.addObject('CollisionPipeline', verbose="0")
rootNode.addObject('BruteForceBroadPhase', name="N2")
rootNode.addObject('BVHNarrowPhase')
rootNode.addObject('CollisionResponse', response="FrictionContactConstraint", responseParams="mu=0.0")
rootNode.addObject('LocalMinDistance', name="Proximity", alarmDistance="8.0", contactDistance="0.5", angleCone="0.01")

solverNode = rootNode.addChild('solverNode')
solverNode.addObject('EulerImplicitSolver', name='odesolver',firstOrder="false", rayleighStiffness='0.0', rayleighMass='0.0')
solverNode.addObject('SparseLDLSolver', name="preconditioner", template="CompressedRowSparseMatrixd")
solverNode.addObject('GenericConstraintCorrection', linearSolver='@preconditioner',printLog=True, name='ResReso')

##########################################
# FEM Model #
##########################################

sphereTranslation = [0,10,0]
model = solverNode.addChild('model')
model.addObject('MeshVTKLoader', name='loader', filename=pathMesh+'sphere.vtk', translation=sphereTranslation)
model.addObject('Mesh',src = '@loader')
model.addObject('MechanicalObject', name='tetras', template='Vec3d', showIndices='false', showIndicesScale='4e-5', rx='0',printLog="0")
# model.addObject('WriteState', name="StateWriter", filename="fullBall.state",period="0.001", writeX=True, writeX0=True, writeV=False, writeF=False, time=0)
model.addObject('UniformMass', totalMass='0.2', printLog='0')
model.addObject('TetrahedronFEMForceField', template='Vec3d',youngModulus=1.0e3,poissonRatio=0.45)

modelCollis = model.addChild('modelCollis')
modelCollis.addObject('MeshSTLLoader', name='loader', filename=pathMesh+'sphere.stl', rotation="0 0 0", translation=sphereTranslation)
#modelCollis.addObject('MeshSTLLoader', name='loader', filename=pathMesh+'sphereFine.stl', rotation="0 0 0", translation=sphereTranslation)
modelCollis.addObject('TriangleSetTopologyContainer', src='@loader', name='container')
modelCollis.addObject('MechanicalObject', name='collisMO', template='Vec3d')
modelCollis.addObject('TriangleCollisionModel',group="0")
modelCollis.addObject('LineCollisionModel',group="0")
modelCollis.addObject('PointCollisionModel',group="0")
modelCollis.addObject('BarycentricMapping')

rotation=[0,0,0]
#rotation=[30,0,0]
planeNode = rootNode.addChild('Plane')
planeNode.addObject('MeshObjLoader', name='loader', filename="mesh/floorFlat.obj", triangulate="true",rotation=rotation)
planeNode.addObject('Mesh', src="@loader")
planeNode.addObject('MechanicalObject', src="@loader", rotation="0 0 0", translation="0 0 0", scale="1")
planeNode.addObject('TriangleCollisionModel',simulated="0", moving="0",group="1",name='TriPlane')
planeNode.addObject('LineCollisionModel',simulated="0", moving="0",group="1")
planeNode.addObject('PointCollisionModel',simulated="0", moving="0",group="1")
planeNode.addObject('OglModel',name="Visual", fileMesh="mesh/floorFlat.obj", color="1 0 0 1",rotation=rotation, translation="0 0 0", scale="1")
planeNode.addObject('UncoupledConstraintCorrection')

return rootNode
89 changes: 89 additions & 0 deletions examples/bouncingBall/softSphereFalling_reduced.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import Sofa
import Sofa.Core
import os
pathSceneFile = os.path.dirname(os.path.abspath(__file__))
pathMesh = os.path.dirname(os.path.abspath(__file__))+'/'
nbrOfModes = 15
# Units: mm, kg, s. Pressure in kPa = k (kg/(m.s^2)) = k (g/(mm.s^2) = kg/(mm.s^2)
plugins=["SofaPython3","SoftRobots","ModelOrderReduction","STLIB",
# normally plugin Sofa.Component is enough but still warning
"Sofa.Component.Visual",
"Sofa.Component.AnimationLoop",
"Sofa.GL.Component.Rendering3D",
"Sofa.Component.Constraint.Lagrangian.Solver",
'Sofa.Component.IO.Mesh',
'Sofa.Component.Playback',
'Sofa.Component.Constraint.Lagrangian.Correction', # Needed to use components [GenericConstraintCorrection]
'Sofa.Component.Engine.Select', # Needed to use components [BoxROI]
'Sofa.Component.LinearSolver.Direct', # Needed to use components [SparseLDLSolver]
'Sofa.Component.Mapping.Linear', # Needed to use components [BarycentricMapping]
'Sofa.Component.Mass', # Needed to use components [UniformMass]
'Sofa.Component.ODESolver.Backward', # Needed to use components [EulerImplicitSolver]
'Sofa.Component.SolidMechanics.FEM.Elastic', # Needed to use components [TetrahedronFEMForceField]
'Sofa.Component.SolidMechanics.Spring', # Needed to use components [RestShapeSpringsForceField]
'Sofa.Component.StateContainer', # Needed to use components [MechanicalObject]
'Sofa.Component.Topology.Container.Dynamic'] # Needed to use components [TetrahedronSetTopologyContainer]

def createScene(rootNode):

rootNode.addObject('RequiredPlugin', pluginName=plugins, printLog=False)

rootNode.addObject('VisualStyle', displayFlags='showVisualModels hideBehaviorModels showCollisionModels hideBoundingCollisionModels showForceFields showInteractionForceFields hideWireframe')
rootNode.gravity=[0,-9810, 0]
rootNode.dt = 0.0001
rootNode.addObject('FreeMotionAnimationLoop')
rootNode.addObject('GenericConstraintSolver', name='GSSolver', maxIterations='10000', tolerance='1e-15')
rootNode.addObject('CollisionPipeline', verbose="0")
rootNode.addObject('BruteForceBroadPhase', name="N2")
rootNode.addObject('BVHNarrowPhase')
rootNode.addObject('CollisionResponse', response="FrictionContactConstraint", responseParams="mu=0.0")
rootNode.addObject('LocalMinDistance', name="Proximity", alarmDistance="8.0", contactDistance="0.5", angleCone="0.01")

solverNode = rootNode.addChild('solverNode')
solverNode.addObject('EulerImplicitSolver', name='odesolver',firstOrder="false", rayleighStiffness='0.0', rayleighMass='0.0')
solverNode.addObject('SparseLDLSolver', name="preconditioner", template="CompressedRowSparseMatrixd")
solverNode.addObject('GenericConstraintCorrection', linearSolver='@preconditioner',printLog=True, name='ResReso')

##########################################
# FEM Model #
##########################################

sphereTranslation = [0,10,0]
modesNode = solverNode.addChild('modesNode')
modesNode.addObject('MechanicalObject', position = [0]*nbrOfModes, name='modes', template='Vec1d', showIndices='false')

model = modesNode.addChild('model')
model.addObject('MeshVTKLoader', name='loader', filename=pathMesh+'sphere.vtk', translation=sphereTranslation)
model.addObject('Mesh',src = '@loader')
model.addObject('MechanicalObject', name='tetras', template='Vec3d', showIndices='false', showIndicesScale='4e-5', rx='0',printLog="0")
# model.addObject('WriteState', name="StateWriter", filename="fullBall.state",period="0.001", writeX=True, writeX0=True, writeV=False, writeF=False, time=0)
model.addObject('UniformMass', totalMass='0.2', printLog='0')
# model.addObject('TetrahedronFEMForceField', template='Vec3d',youngModulus=1.0e3,poissonRatio=0.45)
# model.addObject('HyperReducedTetrahedronFEMForceField' , template = 'Vec3', method = 'large', name = 'reducedFF_modelNode_0', poissonRatio = 0.45, youngModulus = 1.0e3, nbModes = nbrOfModes, prepareECSW = True, performECSW = False, modesPath = 'modes.txt',nbTrainingSet=100,periodSaveGIE=10)
model.addObject('HyperReducedTetrahedronFEMForceField' , template = 'Vec3', method = 'large', name = 'reducedFF_modelNode_0', poissonRatio = 0.45, youngModulus = 1.0e3, nbModes = nbrOfModes, prepareECSW = False, performECSW = True, modesPath = 'modes.txt', RIDPath='RID.txt',weightsPath='weights.txt')

model.addObject('ModelOrderReductionMapping' , input = '@../modes', modesPath = 'modes.txt', output = '@./tetras')

modelCollis = model.addChild('modelCollis')
modelCollis.addObject('MeshSTLLoader', name='loader', filename=pathMesh+'sphere.stl', rotation="0 0 0", translation=sphereTranslation)
#modelCollis.addObject('MeshSTLLoader', name='loader', filename=pathMesh+'sphereFine.stl', rotation="0 0 0", translation=sphereTranslation)
modelCollis.addObject('TriangleSetTopologyContainer', src='@loader', name='container')
modelCollis.addObject('MechanicalObject', name='collisMO', template='Vec3d')
modelCollis.addObject('TriangleCollisionModel',group="0")
modelCollis.addObject('LineCollisionModel',group="0")
modelCollis.addObject('PointCollisionModel',group="0")
modelCollis.addObject('BarycentricMapping')

rotation=[0,0,0]
#rotation=[30,0,0]
planeNode = rootNode.addChild('Plane')
planeNode.addObject('MeshObjLoader', name='loader', filename="mesh/floorFlat.obj", triangulate="true",rotation=rotation)
planeNode.addObject('Mesh', src="@loader")
planeNode.addObject('MechanicalObject', src="@loader", rotation="0 0 0", translation="0 0 0", scale="1")
planeNode.addObject('TriangleCollisionModel',simulated="0", moving="0",group="1",name='TriPlane')
planeNode.addObject('LineCollisionModel',simulated="0", moving="0",group="1")
planeNode.addObject('PointCollisionModel',simulated="0", moving="0",group="1")
planeNode.addObject('OglModel',name="Visual", fileMesh="mesh/floorFlat.obj", color="1 0 0 1",rotation=rotation, translation="0 0 0", scale="1")
planeNode.addObject('UncoupledConstraintCorrection')

return rootNode
Loading

0 comments on commit c43fe21

Please sign in to comment.