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

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?

Chien-Cheng

## Question information

Language:
English Edit question
Status:
Solved
For:
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
Last query:

## This question was reopened

 Revision history for this message Jan Stránský (honzik) said on 2020-12-01: #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:
- 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

 Revision history for this message Chien-Cheng Hung (chiencheng) said on 2020-12-01: #2

Hi Jan,

> 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

 Revision history for this message Jan Stránský (honzik) said on 2020-12-01: #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

 Revision history for this message Chien-Cheng Hung (chiencheng) said on 2020-12-01: #4

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

 Revision history for this message Chien-Cheng Hung (chiencheng) said on 2020-12-02: #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

 Revision history for this message Jan Stránský (honzik) said on 2020-12-02: #6

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

 Revision history for this message Chien-Cheng Hung (chiencheng) said on 2020-12-02: #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

#########################

a=5
b=5
c=5

O.periodic=True

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

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

 Revision history for this message Jan Stránský (honzik) said on 2020-12-02: #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

 Revision history for this message Chien-Cheng Hung (chiencheng) said on 2020-12-02: #9

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