Crop a specific range of the imported packing and distribute it to a specific position

Asked by Chien-Cheng Hung on 2020-12-01

Dear all,

I am trying to simulate a direct shear experiment on a dense packing with particle size distribution (PSD).
For creating a dense packing with PSD, I use makeCloud to generate a loose packing first and then apply isotropic compression to the packing.
To save time for each simulation, I first create a massive loose packing, and after isotropic compression, I export the dense packing as a list for further simulation.

My question is, how do I crop this massive packing into a smaller desired size of packing and distribute it to the position I want?
The purpose of doing this is to achieve identical thickness of the packing for each simulation since different PSD can result in different layer thickness after isotropic compression.

For example, if there is a list of packing with the size of (0,0,0) to (5,5,5) and I want to import this packing in a smaller size of range from (1,1,1) to (4,4,4) and get rid of the rest of packing. After that, I want to distribute this specific size of packing to the position of (10,10,10) to (13,13,13). How can I do to achieve this?

Thanks in advance!

Chien-Cheng

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2020-12-02
Last query:
2020-12-02
Last reply:
2020-12-02

This question was reopened

Jan Stránský (honzik) said : #1

Hello,

> To save time ...

there is also another approach, used e.g. by randomDensePack, create relatively quickly a small periodic sample and then copy it wherever you want.
randomDensePack itself does not support psd input, but the code can be "copy-pasted" to a new function.

> My question is ...

a general approach could be:
- load whole packing
- filter only desired particles, e.g. from (1,1,1) to (4,4,4)
- distribute it to desired position, e.g. (10,10,10) to (13,13,13)

a simple for loop with if condition should do the job..

If this is not what you want, please specify where you have problems

cheers
Jan

Chien-Cheng Hung (chiencheng) said : #2

Hi Jan,

Thanks for your quick reply.

> randomDensePack itself does not support psd input, but the code can be "copy-pasted" to a new function.

I don't really understand this part. How do I create a dense pack with psd by using "copy-pasted the code to a new function" ?
I thought about using randomDensePack instead of using makeCloud and isotropic compression but not sure how to input psd in randomDensePack. Is there an example for it?

> a simple for loop with if condition should do the job..

Okay, I will try this. Thanks!

Cheers,
Chien-Cheng

Jan Stránský (honzik) said : #3

>> randomDensePack itself does not support psd input, but the code can be "copy-pasted" to a new function.
> I don't really understand this part. How do I create a dense pack with psd by using "copy-pasted the code to a new function" ?
> I thought about using randomDensePack instead of using makeCloud and isotropic compression but not sure how to input psd in randomDensePack. Is there an example for it?

This is the point, randomDensePack as it is does not support psd input.
"copy-pasted the code to a new function" means take the code [1] and create your own function with psd support :-)
Just a note, what randomDensePack does is basically makeCloud and isotropic compression. So the "copy-paste" could mean just inspiration (e.g. in the part of periodicity), not necessarily literal copy paste.

cheers
Jan

[1] https://gitlab.com/yade-dev/trunk/-/blob/master/py/pack/pack.py#L464

Chien-Cheng Hung (chiencheng) said : #4

Thanks Jan Stránský, that solved my question.

Chien-Cheng Hung (chiencheng) said : #5

Hi Jan,

Is it possible that you could show me an example about how to move particles?
For example, a pack of particles range from (0,0,0) to (1,1,1) and move all of them with equal distance to the coordinates of (2,2,2) and (3,3,3).
Or it there an example in the Yade documentation?
I'd appreciate that, thanks!

Cheers,
Chien-Cheng

Jan Stránský (honzik) said : #6

> please specify where you have problems
Also, what is "particles", "a pack", ...?
A MWE [1] would be great
cheers
Jan

[1] https://www.yade-dem.org/wiki/Howtoask

Chien-Cheng Hung (chiencheng) said : #7

> Also, what is "particles", "a pack", ...?

Sorry, it should be just "a packing"..

> A MWE [1] would be great

Here's the MWE showing how I follow what you suggested previously

#########################
from yade import pack, ymport

a=5
b=5
c=5
RADIUS_dimension=0.00025

length=a*(2*RADIUS_dimension)
height=b*(2*RADIUS_dimension)
width=c*(2*RADIUS_dimension)
thickness=RADIUS_dimension

O.periodic=True

O.cell.hSize=Matrix3(length,0,0,0,3*height,0,0,0,width)

### load whole packing
packing = ymport.text("mypacking.spheresisoCompression")

### filter only desired particles
for i in range(0,len(packing)):
    if packing[i].state.pos[1] > height and packing[i].state.pos[1] < 2*height:
        ### distribute it to desired position <-- not sure how to do this part
        packing[i].state.pos[0] = packing[i].state.pos[0] + 5*thickness
        packing[i].state.pos[1] = packing[i].state.pos[1] + 5*thickness
        packing[i].state.pos[2] = packing[i].state.pos[2] + 5*thickness
        O.bodies.append(packing[i])
#########################

I can obtain the desired packing but they still remain at the same position. So my question is how to distribute (or move) the desired particles to a desired position. I hope this is clear to you. I will ask more specifically next time!

Cheers,
Chien-Cheng

Best Jan Stránský (honzik) said : #8

> Here's the MWE

IOError: [Errno 2] No such file or directory: 'mypacking.spheresisoCompression'

> for i in range(0,len(packing)):

do you need "i"? If not, it is more understandable and clean to iterate bodies directly
###
for b in packing:
    if b.state.pos[1] > height and b.state.pos[1] < 2*height:
        b.state.pos[0] = b.state.pos[0] + 5*thickness
        ...
###

> ### distribute it to desired position <-- not sure how to do this part

MWE (following OP):
###
# (0,0,0)-(5,5,5) packing
spheres = [sphere((x,y,z),.5) for x in range(6) for y in range(6) for z in range(6)]

# fitler (1,1,1)-(4,4,4)
def sphereWanted(b):
    x,y,z = b.state.pos
    return x >= 1 and x <= 4 and y >= 1 and y <= 4 and z >= 1 and z <= 4
spheres = [b for b in spheres if sphereWanted(b)]

# shift
for b in spheres:
    b.state.pos += (9,9,9)

O.bodies.append(spheres)
###

cheers
Jan

Chien-Cheng Hung (chiencheng) said : #9

Thanks Jan Stránský, that solved my question.