Granular material

This part is dedicated to the generation of granular material samples. On the whole the definition of a granular sample is separeted in three steps:

  1. generation of a list of boundary radii according to a known granulometry
  2. positioning of grains with the generated boundary radii according to a deposit method
  3. creation of the real sample of particles

In the following sections are presented what functions are available within the current version of LMGC90’s preprocessor for each of these step. Many examples using these functions are available in the examples of LMGC90.

List of radii

A list of radii following a given granulometry is generated. The available functions are:


Let’s say we want to generate a sample of particules which each radius is randomly chosen between two radii. This is done thank to:

nb_particles = 10000
radius_min   = 1.0
radius_max   = 2.5
radii = granulo_Random(nb_particles, radius_min, radius_max)


Once the list of bounded radii is obtained, the next step is to determine where to put grains in space. This is the role of the deposit functions which takes the list of radii as input and give a list of coordinates as output. There are two kinds of deposit function available: loose deposit on a lattice or dense deposit:

Dense deposit of particles are performed minimizing a potential. In our case it is the gravity potential which is minimized.

Warning: if the number of particles laid is inferior to the number of input radii, the granulometry may be changed on the output.

Warning: to avoid interpenetration between particles, a shrink based on the size of particles is used.


Using the radii variable generated in previous example, let us deposit it in 2-dimensionnal box:

lx = 150.
ly = 100.
[nb_laid_particles, coors] = depositInBox2D(radii,lx,ly)

Particle generation

Last step is to generate the avatar corresponding to each particle.
Several simple particle types can be automatically generated:


deposit of triangles

Finally the container of avatar must be filled:

mat = material(name='TDURx', materialType='RIGID', density=100.)
mod = model(name='rigid', physics='MECAx', element='Rxx2D', dimension=2)
bodies = avatars()
nb_vertices = 3
for i in range(nb_laid_particles):
  body = rigidPolygon(radius=radii[i], center=coors[2*i:2*i+2], nb_vertices=nb_vertices, model=mod, material=mat, color='BLUEx')

Wall generation

Even if in most case straight plans are used to define the wall of a box, it is sometimes desired to have a rough wall like a cluster of disks/spheres. Here are the functions to create such a wall in a single line:


deposit of triangles with left wall

To complete our example let’s create three walls for the box using the three first functions just to illustrate the differences between them. First the left wall:

max_radius = max(radii)
mut    = material(name='TDURx', materialType='RIGID', density=1000.)
left   = roughWall(  center=[-radius_max, 0.5*ly], theta=-0.5*math.pi, l=ly + 2.*radius_max,
                     r=radius_max, model=mod, material=mut, color='WALLx')
left.imposeDrivenDof(component=[1,2,3], dofty='vlocy')
deposit of triangles with left and right walls

Then the right wall:

right  = fineWall(   center=[lx+radius_max, 0.5*ly], theta= 0.5*math.pi, l=ly + 2.*radius_max,
                     r=radius_max, model=mod, material=mut, color='WALLx')
right.imposeDrivenDof(component=[1,2,3], dofty='vlocy')
deposit of triangles with left, right and bottom walls

And finally the bottom of the box:

bottom = smoothWall( center=[0.5*lx, -radius_max], theta=0., l=lx + 2.*radius_max,
                     h=radius_max, nb_polyg=12, model=mod, material=mut, color='WALLx')
bottom.imposeDrivenDof(component=[1,2,3], dofty='vlocy')

See this file for the complete generation script.