Making a sphere layer with certain orientation

Asked by Chien-Cheng Hung on 2020-05-25

Dear all,

I am trying to generating a sphere layer with a certain orientation.
For example, I would like to generate a layer intersecting Z-axis with 45 degrees (taking X-axis as the front).
Is it possible to do this in Yade?
Thanks!

Cheers,
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-05-27
Last query:
2020-05-27
Last reply:
2020-05-27
Jan Stránský (honzik) said : #1

Hello,

> Is it possible to do this in Yade?

yes, of course.
Just create spheres with desired size at desired position to form desired sphere layer.

To get a better answer, please provide more info:
- what "sphere layer" is
- if / what you have tried / thought of, why it did not work...

cheers
Jan

Chien-Cheng Hung (chiencheng) said : #2

Hi Jan,

Thanks for your quick reply!

> - what "sphere layer" is

I should say a "granular" layer instead of a sphere layer. It means a layer composed of several spheres.

> - if / what you have tried / thought of, why it did not work...

Currently, I'm using the function makeCloud [1] to generate a random loose packing of spheres, and then I would apply the isotropic compaction to make a dense packing (I call it a granular layer). But in this function, I can only assign a vector to minCorner and maxCorner so that the length of generated loose packing is always parallel to the X-, Y-, Z-axis. What I would like to do is to generate a random packing in which its length can be oriented to the axis with certain degrees. Is this clear to you?

Thanks again!

Cheers,
Chien-Cheng

[1] https://yade-dem.org/doc/yade.pack.html?highlight=makecloud#yade._packSpheres.SpherePack.makeCloud

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

yes, thanks. So basically:
1) create the aligned layer
2) rotate it

### MWE
from yade import pack
# "aligned" layer
layer = pack.regularOrtho(pack.inAlignedBox((0,0,0),(20,20,5)),1,0)
# rotation (can be also any other transformation, like shift, scale etc.)
center = Vector3(0,0,0) # center of rotation
rotation = Quaternion((1,0,0),.25*pi) # Quaternion(rotationAxis,rotationAngle)
for b in layer: # apply the transformation for each sphere of the layer
   b.state.pos = center + rotation * (b.state.pos - center)
O.bodies.append(layer)
###

cheers
Jan

Chien-Cheng Hung (chiencheng) said : #4

Hi Jan,

Thanks for your information. It's very useful.

I tried to apply the same trick to "sp.makeCloud()" because I would like to assign material properties and different particles size to the spheres.

###
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(20,20,5), rMean = 1)
center = Vector3(0,0,0)
rotation = Quaternion((1,0,0),.25*pi)
for b in sp:
    b.state.pos = center + rotation * (b.state.pos - center)
O.bodies.append([utils.sphere(s[0],s[1]) for s in sp])
###

However, the terminal shows "AttributeError: 'tuple' object has no attribute 'state'" after I ran the above code.

How do I rotate a random loose packing by using makeCloud?

Cheers,
Chien-Cheng

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

you use
for center,radius in sp: # [1]
not directly bodies

Try:
###
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(20,20,5), rMean = 1)
center = Vector3(0,0,0)
rotation = Quaternion((1,0,0),.25*pi)
for c,r in sp:
    c = center + rotation * (c - center)
    O.bodies.append(utils.sphere(c,r))
###

cheers
Jan

[1] https://yade-dem.org/doc/yade.pack.html#yade._packSpheres.SpherePack

Chien-Cheng Hung (chiencheng) said : #6

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