ExamplePreviousNext


Random packing

Whole script

The script is written in Python and utilizes the netdem library to perform a simulation. It sets up a simulation environment with a defined boundary, contact models, triangular meshes, particle packs, walls, gravity, data dumping, and runs the simulation. It is important to note that the script assumes the required netdem library is properly installed and accessible in the Python environment.

import netdem

sim = netdem.Simulation()
sim.domain_manager.SetBound(-0.6, -0.6, -0.6, 0.6, 0.6, 0.6)
sim.domain_manager.SetCellSpacing(0.3, 0.3, 0.3)

cnt_model = netdem.LinearSpring(2.0e6, 1.0e6, 0.7, 0.5)
cnt_model_prt = sim.scene.InsertContactModel(cnt_model)
sim.scene.SetNumberOfMaterials(1)
sim.scene.SetCollisionModel(0, 0, cnt_model_prt)

tri_mesh = netdem.TriMesh()
tri_mesh.InitFromSTL("data/particle_template.stl")
tri_mesh.Decimate(400)
tri_mesh.MakeConvex()
tri_mesh.AlignAxes()
tri_mesh.SetSize(0.1)
tri_mesh_ptr = sim.scene.InsertShape(tri_mesh)

pack_generator = netdem.PackGenerator()
particle_list = pack_generator.GetGridPack(1, 1, 0.2, 0, 0, 0.4, 5, 5, 1, tri_mesh_ptr)
for p in particle_list:
    p.SetVelocity(0, 0, -2.0)

wall_box = netdem.WallBoxPlane(1, 1, 1, 0, 0, 0)
wall_box.ImportToScene(sim.scene)

grav = netdem.Gravity()
grav.Init(sim)
sim.modifier_manager.Insert(grav)
sim.modifier_manager.Enable(grav.label)

data_dumper = netdem.DataDumper()
data_dumper.Init(sim)
data_dumper.SetRootPath("tmp/out/")
data_dumper.SetSaveByCycles(100)
data_dumper.dump_contact_info = True
data_dumper.dump_wall_info = True
data_dumper.SaveShapeInfoAsSTL()
sim.modifier_manager.Insert(data_dumper)
sim.modifier_manager.Enable(data_dumper.label)

for i in range(20):
    sim.scene.InsertParticle(particle_list)
    sim.Run(0.1)

sim.Run(2.0)

Step-by-step explaination

Below is a detailed documentation of the script, explaining each line and its purpose.

import netdem

This line imports the netdem module, which contains classes and functions necessary for the simulation.

sim = netdem.Simulation()

Creates an instance of the Simulation class and assigns it to the variable sim. This object will be used to manage the simulation.

sim.domain_manager.SetBound(-0.6, -0.6, -0.6, 0.6, 0.6, 0.6)

Sets the boundary of the simulation domain using the SetBound method of the domain_manager object. The specified coordinates (-0.6, -0.6, -0.6) and (0.6, 0.6, 0.6) define the minimum and maximum bounds of the simulation domain in three dimensions.

sim.domain_manager.SetCellSpacing(0.3, 0.3, 0.3)

Sets the cell spacing of the simulation domain using the SetCellSpacing method of the domain_manager object. The specified values (0.3, 0.3, 0.3) determine the size of each cell in the simulation domain grid.

cnt_model = netdem.LinearSpring(2.0e6, 1.0e6, 0.7, 0.5)

Creates an instance of the LinearSpring class from the netdem module and assigns it to the variable cnt_model. This model represents a linear spring with specified parameters: stiffness, damping, restitution, and friction.

cnt_model_prt = sim.scene.InsertContactModel(cnt_model)

Inserts the contact model (cnt_model) into the simulation scene using the InsertContactModel method of the scene object. The resulting contact model is assigned to the variable cnt_model_prt for later use.

sim.scene.SetNumberOfMaterials(1)
sim.scene.SetCollisionModel(0, 0, cnt_model_prt)

Sets the number of materials in the simulation scene to 1 and assigns the contact model (cnt_model_prt) to the collision model at index 0. These operations are performed using methods from the scene object.

tri_mesh = netdem.TriMesh()

Creates an instance of the TriMesh class from the netdem module and assigns it to the variable tri_mesh. This object represents a triangular mesh.

tri_mesh.InitFromSTL("data/particle_template.stl")

Initializes the tri_mesh object by loading a triangular mesh from an STL file located at "data/particle_template.stl". The provided STL file is used as a template for particles in the simulation.

tri_mesh.Decimate(400)

Decimates the loaded triangular mesh, reducing the number of polygons while preserving the overall shape. The size of the decimation is determined by the parameter 400.

tri_mesh.MakeConvex()

Converts the triangular mesh into a convex hull representation using the MakeConvex method. This step simplifies the geometry and improves simulation performance.

tri_mesh.AlignAxes()

Aligns the axes of the triangular mesh using the AlignAxes method. This step ensures that the mesh aligns properly with the simulation coordinate system.

tri_mesh.SetSize(0.1)

Sets the size of the triangular mesh using the SetSize method. The specified value (0.1) determines the new size of the mesh.

tri_mesh_ptr = sim.scene.InsertShape(tri_mesh)

Inserts the triangular mesh object into the simulation scene using the InsertShape method of the scene object. The resulting shape is assigned to the variable tri_mesh_ptr for later use.

pack_generator = netdem.PackGenerator()

Creates an instance of the PackGenerator class and assigns it to the variable pack_generator. This object is responsible for generating particle packs in the simulation.

particle_list = pack_generator.GetGridPack(1, 1, 0.2, 0, 0, 0.4, 5, 5, 1, tri_mesh_ptr)

Generates a grid-based particle pack using the GetGridPack method of the pack_generator object. The generated particles are assigned to the particle_list variable. The parameters provided determine the number of particles in each dimension of the grid (1 particle in the x-direction, 1 particle in the y-direction), the spacing between particles (0.2), the position of the origin of the grid (0, 0, 0.4), the number of particles in each dimension (5 particles in the x-direction, 5 particles in the y-direction), the height of the particle pack (1), and the shape pointer (tri_mesh_ptr) used as a template for the particles.

for p in particle_list:
    p.SetVelocity(0, 0, -2.0)

Sets the initial velocity of each particle in the particle_list to (0, 0, -2.0) using the SetVelocity method. This sets a downward velocity for the particles.

wall_box = netdem.WallBoxPlane(1, 1, 1, 0, 0, 0)
wall_box.ImportToScene(sim.scene)

Creates an instance of the WallBoxPlane class with specified dimensions (1, 1, 1) and position (0, 0, 0). Then, it imports the wall box object into the simulation scene using the ImportToScene method of the wall_box object. This creates a box-shaped wall in the simulation.

grav = netdem.Gravity()
grav.Init(sim)
sim.modifier_manager.Insert(grav)
sim.modifier_manager.Enable(grav.label)

Creates an instance of the Gravity class and assigns it to the variable grav. The Init method initializes the gravity object using the sim simulation object. The gravity object is then inserted into the modifier manager of the simulation and enabled. This ensures that gravity affects the particles in the simulation.

data_dumper = netdem.DataDumper()
data_dumper.Init(sim)
data_dumper.SetRootPath("tmp/out/")
data_dumper.SetSaveByCycles(100)
data_dumper.dump_contact_info = True
data_dumper.dump_wall_info = True
data_dumper.SaveShapeInfoAsSTL()
sim.modifier_manager.Insert(data_dumper)
sim.modifier_manager.Enable(data_dumper.label)

Creates an instance of the DataDumper class and assigns it to the variable data_dumper. The Init method initializes the data dumper object using the sim simulation object. The following lines specify various settings for the data dumper, such as the root path for saving files ("tmp/out/"), the save frequency (every 100 cycles), and the types of data to be dumped (contact information and wall information). Additionally, the SaveShapeInfoAsSTL method is called to enable saving shape information as STL files. Finally, the data dumper object is inserted into the modifier manager of the simulation and enabled.

for i in range(20):
    sim.scene.InsertParticle(particle_list)
    sim.Run(0.1)

In a loop that iterates 20 times, particles from the particle_list are inserted into the simulation scene using the InsertParticle method. Then, the simulation is run for a duration of 0.1 time units using the Run method. This loop allows the particles to settle in the simulation before further simulation steps.

sim.Run(2.0)

Finally, the simulation is run for a duration of 2.0 time units using the Run method. This completes the simulation process.

Simulation result


ExamplePreviousNext