58. Appendix 4: agxPythonModules

This section documents AGX python modules that are located in data/python/modules/agxPythonModules/.

58.1. Replace particleEmitter with rigidBodyEmitter

ParticleEmitters can only emit spherical bodies that belong to a particleSystem, while a rigidBodyEmitter can emit arbitrary rigid bodies that are treated like any other rigid body in the simulation. Rigid bodies are generally more computationally expensive than particles in a particleSystem, but useful for modeling granular systems of non-spherical bodies. A common workflow is to make prototype simulations of the system with particleEmitters and particleSystems, to figure out the rough 3D design and control of the system, and then substitute the particleEmitters with rigidBodyEmitters. Making the modeling cycle of the system more effective. This requires a systematic way of replacing an agx::ParticleEmitter with an agx::RigidBodyEmitter.

The script replaceParticleEmitterWithRigidBodyEmitter.py in the directory data/python/modules/agxPythonModules/utils, takes a serialized AGX simulation as input and replaces all the particle emitters in the simulation with rigid body emitters and saves the resulting simulation as a new .agx file. After setup of the AGX environment variables the utility script can be called from the command line with:

python -m agxPythonModules.utils.replaceParticleEmitterWithRigidBodyEmitter <path/to/simulation.agx>

By default the resulting simulation is saved as output.agx. It is possible to specify the output name with command line argument --output <name/of/output.agx>. You can then run the simulation and record a journal with the command agxviewer output.agx --journalRecord --journalIncrementalStructure.

The default geometries used as templates are taken from the data/models/convex_stones directory. It is possible to create and use a new shape library, by using the --shapeLibrary command line argument. The shape library is a directory with one .obj file per shape. The shapes must be convex. The size of the rigid body template are estimated using the diagonalized inertia tensor, of the rigid body, assuming uniform mass distribution and a cuboid shape:

\[\begin{split}x = \sqrt{6m^{-1} (Izz + Iyy - Ixx)} \\ y = \sqrt{6m^{-1} (Izz + Ixx - Iyy)} \\ z = \sqrt{6m^{-1} (Iyy + Ixx - Izz)}\end{split}\]

Choosing the smallest of \(x,y,z\) as the size is a good approximation of how mechanical sieving measures the size of rocks. The distributionTable of the rigidBodyEmitter is created by scaling the rocks to match the size of the previously used particles.

The material of the rigid bodies are copied directly from the particles materials. This can lead to unexpected changes in the bulk granular flow, since the rigid bodies have different geometry. Recalibration of the material properties can be necessary.

The friction model for rigid bodies in AGX is by default IterativeProjectedConeFriction, with the solve type SPLIT. Since these simulations often contains a large contact system the script changes the solve type to ITERATIVE. This trades realistic friction for performance. Depending on the application, it possible to speed this up even more together with agxSDK::MergeSplitHandler - AMOR.

A step-by-step description of the workflow when modeling granular flows with spherical particles and rigid bodies:

  1. Do prototype simulations with spherical particleSystems and particleEmitters.

  2. Export the simulation as an .agx file.

  3. [Optionally] Create your own shape library. One shape per .obj file.

  4. Run the script replaceParticleEmitterWithRigidBodyEmitter.py to replace particleEmitters with rigidBodyEmitters.

  5. Run the new simulation with correct solver settings and journal configuration.

  6. Post-process the results.

  7. If needed, return to point 1 and re-design the system.