Dense Packing of Normal Distribution in Rectangular Prism

Asked by Christopher Kozuch

I am trying to pack a normal distribution of particles into a rectangular prism. The porosity should be about 0.45, but I don't know how many particles there should be. I have tried using the code below, but I just get smaller particles instead of denser packing.

sp=pack.SpherePack()
sp.makeCloud(minCorner=Vector3(0.,0.,0.),maxCorner=Vector3(5,5,0.6),num=10000,porosity=0.45,psdSizes=[0.01,0.08,0.15],psdCumm=[0,0.5,1])
sp.toSimulation()

I also tried to use randomDensePack(), but I couldn't make a normal distribution. Is there a different method I should be using?

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Christopher Kozuch
Solved:
Last query:
Last reply:
Revision history for this message
Jérôme Duriez (jduriez) said :
#1

Hello,

The good news is that you're from far not the first one to face such issue. A first quick search for "psd porosity" in the Launchpad answers page returns many answered questions very similar to yours ;-)

I'd suggest more or less randomly to give a close look to e.g. https://answers.launchpad.net/yade/+question/270818 (it has the advantage to be recent)

As you will see, makeCloud can only be used to ... make a cloud: a particle sample in a "gaseous" state. In particular you have no chance to get an actual sample with the porosity equal to the "porosity" attribute value of makeCloud, if this value is the one of a solid-like sample. I understand it's weird...

Then, the idea is to apply in a 2d step a mechanical loading (isotropic compression, typically) to this cloud to obtain the desired porosity. Regarding this stage, a tutorial example frequently refered to in previous questions will definitively help. See https://github.com/yade/trunk/blob/master/examples/triax-tutorial/script-session1.py#L141

Revision history for this message
Christopher Kozuch (chris-kozuch) said :
#2

Jerome,

Thank you for your reply. I did take a look a the tutorial you mentioned, as well a similar one that used gravity. The problem for me is that I need to fill the rectangular prism that I specified. I tried starting with a bigger volume and compressing that, but I was never able to achieve the exact dimensions I am looking for.

Chris

Revision history for this message
Jérôme Duriez (jduriez) said :
#3

The rectangular prism 5*5*0.6, you mean ? If these sizes matter for you, did you try to use isotropic "internal" compression ? The spheres expand rather than the walls move inwards.
https://yade-dem.org/doc/yade.wrapper.html#yade.wrapper.TriaxialCompressionEngine.internalCompaction

Doing so, the initial "rectangle" defined by makeCloud won't be affected. This is the default behavior by the way (?)

Revision history for this message
Christopher Kozuch (chris-kozuch) said :
#4

I guess I should have been more specific. I need the particles to remain in the normal distribution I mentioned in my first post. I was really hoping there was a function that would continue to add particles with sizes that satisfy that normal distribution into the box I defined until the porosity I want is reached. Does such a function exist?

Revision history for this message
Gary Pekmezi (gpekmezi) said :
#5

If I understand the problem correctly, below is how I would start to approach it. Note that it is basically a trial-and-error process.

1) Start with a high angle of friction (say 45 degrees)

2) Pack a prism with 1.5x-2x the volume to abut 80% porosity . To do so , you probably need to run it a couple of times to identify the number of particles that will get you there.

3) Run internal compaction to a threshold confinement pressure in conjunction with scaling until the prism dimensions match the desired dimensions. If the confinement is reached prior to the required dimensions, go back to 1) and try with more spheres. Below is how I scale during internal compaction:
       initialporosity=triax.porosity #porosity before internal compaction
      O.run(1000, True) # run some internal compaction
      packScale=(((1.0-initialporosity)/triax.porosity)**(1.0/3.0)) # identify scaling factor from porosity change
      sp.scale(packScale) # scale the packing so the psd goes back

 4) If the mean stress at this point is zero, you do not have enough spheres. Go back to 1) and try more spheres. Else, if the mean stress is greater than zero proceed to the final step

5) Lower the friction angle until desired porosity is achieved

Revision history for this message
Gary Pekmezi (gpekmezi) said :
#6

Correction in step 3). I meant to say "try with less spheres"

Revision history for this message
Jérôme Duriez (jduriez) said :
#7

As a side note about #4, processing an internal compaction won't affect the normal feature of your psd, even though it will (homothetically) affect the actual size values, obviously.

Then, what kind of contact laws do you use ? With the most classical contact laws, particle size values do not affect Yade simulations.

Revision history for this message
Christopher Kozuch (chris-kozuch) said :
#8

Thank you to both of you, that worked. To answer Jerome's questions, I am exporting the particles to perform external analysis, so that why the particle sizes were important.