ParallelHexahedronFEMForceField
ParallelHexahedronFEMForceField is the multi-threaded equivalent of HexahedronFEMForceField.
This implementation is the most efficient when:
1) the number of hexahedron is large (> 1000)
2) the global system matrix is not assembled. It is usually the case with a CGLinearSolver templated with GraphScattered types.
3) the method is 'large'. If the method is 'polar' or 'small', addForce
is executed sequentially, but addDForce
in parallel.
The following methods are executed in parallel:
addForce
for method 'large'.addDForce
The method addKToMatrix
is not executed in parallel.
This method is called with an assembled system, usually with a direct solver or a CGLinearSolver templated with types different from GraphScattered.
In this case, the most time-consuming step is to invert the matrix. This is where efforts should be put to accelerate the simulation.
Parallel implementation of a linear elastic material using hexahedral finite elements.
Vec3d
Templates:
- Vec3d
Target: MultiThreading
namespace: multithreading::component::forcefield::solidmechanics::fem::elastic
parents:
- HexahedronFEMForceField
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 |
poissonRatio | FEM Poisson Ratio in Hooke's law [0,0.5[ | 0.45 |
youngModulus | FEM Young's Modulus in Hooke's law | 5000 |
method | "large" or "polar" or "small" displacements | large |
updateStiffnessMatrix | 0 | |
gatherPt | number of dof accumulated per threads during the gather operation (Only use in GPU version) | |
gatherBsize | number of dof accumulated per threads during the gather operation (Only use in GPU version) | |
stiffnessMatrices | Stiffness matrices per element (K_i) | |
initialPoints | Initial Position | |
nbThreads | If not yet initialized, the main task scheduler is initialized with this number of threads. 0 corresponds to the number of available cores on the CPU. -n (minus) corresponds to the number of available cores on the CPU minus the provided number. | 0 |
taskSchedulerType | Type of task scheduler to use. | _default |
Visualization | ||
drawing | draw the forcefield if true | 1 |
drawPercentageOffset | size of the hexa | 0.15 |
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
ParallelHexahedronFEMForceField.scn
<?xml version="1.0" ?>
<Node name="root" dt="0.02">
<RequiredPlugin name="MultiThreading"/> <!-- Needed to use components [ParallelHexahedronFEMForceField] -->
<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.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [IdentityMapping] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [HexahedronSetTopologyContainer, HexahedronSetTopologyModifier, QuadSetTopologyContainer, QuadSetTopologyModifier] -->
<RequiredPlugin name="Sofa.Component.Topology.Mapping"/> <!-- Needed to use components [Hexa2QuadTopologicalMapping] -->
<RequiredPlugin name="Sofa.GL.Component.Rendering3D"/> <!-- Needed to use components [OglModel] -->
<VisualStyle displayFlags="showBehaviorModels hideForceFields showWireframe" />
<Node name="M1">
<EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MechanicalObject name="Volume" template="Vec3"/>
<UniformMass vertexMass="1" />
<RegularGridTopology name="grid" nx="8" ny="8" nz="40" xmin="-1.5" xmax="1.5" ymin="-1.5" ymax="1.5" zmin="0" zmax="19" />
<HexahedronSetTopologyContainer name="Container" src="@grid"/>
<HexahedronSetTopologyModifier name="Modifier" />
<BoxROI box="-1.5 -1.5 0 1.5 1.5 0.0001" name="box"/>
<FixedProjectiveConstraint indices="@box.indices" />
<ParallelHexahedronFEMForceField name="FEM" youngModulus="400000" poissonRatio="0.4" method="large" updateStiffnessMatrix="false"/>
<Node name="surface">
<QuadSetTopologyContainer name="Container" />
<QuadSetTopologyModifier name="Modifier" />
<Hexa2QuadTopologicalMapping input="@../Container" output="@Container" />
<Node name="Visu">
<OglModel name="Visual" color="red" />
<IdentityMapping input="@../../Volume" output="@Visual" />
</Node>
</Node>
</Node>
</Node>
def createScene(root_node):
root = root_node.addChild('root', dt="0.02")
root.addObject('RequiredPlugin', name="MultiThreading")
root.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
root.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select")
root.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
root.addObject('RequiredPlugin', name="Sofa.Component.Mass")
root.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
root.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Grid")
root.addObject('RequiredPlugin', name="Sofa.Component.Visual")
root.addObject('RequiredPlugin', name="Sofa.Component.Mapping.Linear")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Dynamic")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Mapping")
root.addObject('RequiredPlugin', name="Sofa.GL.Component.Rendering3D")
root.addObject('VisualStyle', displayFlags="showBehaviorModels hideForceFields showWireframe")
m1 = root.addChild('M1')
m1.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false", rayleighStiffness="0.1", rayleighMass="0.1")
m1.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1.addObject('MechanicalObject', name="Volume", template="Vec3")
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', name="grid", nx="8", ny="8", nz="40", xmin="-1.5", xmax="1.5", ymin="-1.5", ymax="1.5", zmin="0", zmax="19")
m1.addObject('HexahedronSetTopologyContainer', name="Container", src="@grid")
m1.addObject('HexahedronSetTopologyModifier', name="Modifier")
m1.addObject('BoxROI', box="-1.5 -1.5 0 1.5 1.5 0.0001", name="box")
m1.addObject('FixedProjectiveConstraint', indices="@box.indices")
m1.addObject('ParallelHexahedronFEMForceField', name="FEM", youngModulus="400000", poissonRatio="0.4", method="large", updateStiffnessMatrix="false")
surface = M1.addChild('surface')
surface.addObject('QuadSetTopologyContainer', name="Container")
surface.addObject('QuadSetTopologyModifier', name="Modifier")
surface.addObject('Hexa2QuadTopologicalMapping', input="@../Container", output="@Container")
visu = surface.addChild('Visu')
visu.addObject('OglModel', name="Visual", color="red")
visu.addObject('IdentityMapping', input="@../../Volume", output="@Visual")