How to add rotation on the Boxfactory?

Asked by Mu Wh

Hello everyone!
I am a new user of Yade and I want to simulate rotational powder dropping in the unsealed cylinder. I tried to add rotational movement on the Boxfactory through the RotationEngine but the terminal shows “SyntaxError: invalid syntax”. I have consulted question/647827[1], but I don’t know how to deal with it. Could you give me some advice?
Moreover, I also encountered some problems in the process of beginning to learn Yade, could I trouble you to answer problems?
1. In the below code, the steelID and "316lsteel" can present the defined material. However, the description of material selection between CylinderID and BoxFactory is different. I want to know the difference between ‘label’ and ‘id’.
2. In the below code, the material of the sphere and geometry is 316Lsteel. I want to know the difference between frictionAngle is defined in O.materials.append and the frictAngle in Ip2_FrictMat_FrictMat_MindlinPhys. In the Yade document, the frictionAngle means Contact friction angle (in radians), and frictAngle means Instance of MatchMaker determining how to compute interaction’s friction angle.
3. In the Hertz-Mindlin model of the YADE document, the normal coefficient of restitution(en) can be considered as equal to the shear coefficient of restitution(es), and I would like to confirm to you that es = en = e/sqrt(2)? e is the restitution coefficient.
4. In Boxfactory, the meaning of mask is groupMask to apply for newly created spheres. In packs.py[2],the value of mask is 5. I am confused about whether the value mask has the same meaning as the value wallmask in geom.factbox, i.e – determines which walls will be created spheres, in the order -x (1), +x (2), -y (4), +y (8), -z (16), +z (32). The numbers are ANDed; the default 63 means to create spheres in all walls.
5. When RotationEngine is not applied to Boxfactory, the following warning appears at the terminal when emulation begins. Could you give me some advice to deal with it?
 (1) Shop:482 static yade::Real yade::Shop::PWaveTimeStep(boost::shared_ptr<yade::Scene>): PWaveTimeStep has not found any suitable spherical body to calculate dt. dt is set to 1.0;
 (2) InsertionSortCollider:374 virtual void yade::InsertionSortCollider::action(): verletDist is set to 0 because no spheres were found. It will result in suboptimal performances, consider setting a positive verletDist in your script.

The rotational powder-dropping code is as follows:
from yade import pack, geom
steelID= O.materials.append(FrictMat(density=7800,young=2.2e9,poisson=.3,frictionAngle=math.atan(.62),label="316lsteel"))
CylinderID=O.bodies.append(geom.facetCylinder((0,0,10), radius=10, height=20, orientation=Quaternion((1, 0, 0), 0), wire=False,segmentsNumber=60, dynamic=False, wallMask=6, angleRange=None, closeGap=False, radiusBottomInner=-1,material='316lsteel'))
O.engines=[
       ForceResetter(),
       InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
       InteractionLoop(
               [Ig2_Facet_Sphere_ScGeom(),Ig2_Sphere_Sphere_ScGeom()],
               [Ip2_FrictMat_FrictMat_MindlinPhys(en=0.636, es=0.636,frictAngle=math.atan(.62))],
               [Law2_ScGeom_MindlinPhys_Mindlin()]
        ),
        FactoryID=BoxFactory(
                maxParticles=1000,
                extents=(3, 3, 3),
                center=(3, 3, 10),
                rMin=0.28,
                rMax=0.29,
                vMin=0,
                vMax=0
                vAngle=0,
                massFlowRate=10000.,
                normal=(0, 0, -1),
                label='factory',
               materialId=steelID

        ),
          RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=0.1, rotateAroundZero=True, zeroPoint=(0, 0, .10),ids=FactoryID),# factory motion
        NewtonIntegrator(gravity=(0,0,-9.81))
]
O.dt=.5e-4*utils.PWaveTimeStep()
O.saveTmp()
O.run()
[1] https://answers.launchpad.net/yade/+question/647827
[2] https://gitlab.com/yade-dev/trunk/blob/master/examples/packs/packs.py

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
Last query:
Last reply:
Revision history for this message
Jan Stránský (honzik) said :
#1

Hello,

> I am a new user of Yade

welcome :-)

> the terminal shows “SyntaxError: invalid syntax”

the terminal shows much more information:
###
line 19
vMax=0
SyntaxError: invalid syntax. Perhaps you forgot a comma?
###
Specifically:
line 19 ... line in the script where the problem is
vMax=0 ... the problematic code
Perhaps you forgot a comma? ... some more hints

From the code and message, the correct code should be:
vMax=0, # with the comma, since it is a part of comma-separated parameters of BoxFactory

> Moreover ... could I trouble you to answer problems?

Yes, of course you can "trouble" us.
But please next time follow our requirements and open a separate question for separate problems ([2], point 5).

> 1. In the below code, the steelID and "316lsteel" can present the defined material. However, the description of material selection between CylinderID and BoxFactory is different. I want to know the difference between ‘label’ and ‘id’.

id:
    - number
    - automatically assigned by Yade (user cannot choose it arbitrarily)
    - it is more universal (usable basically everywhere in Yade)
    - less informative (material 1 does not say much...)

label:
    - string
    - assigned by user
    - more informative ("steel", "wallMaterial" etc., clear what it means)
    - less universal (usage must be prepared "in advance" to accept string label)

> 2. In the below code, the material of the sphere and geometry is 316Lsteel. I want to know the difference between frictionAngle is defined in O.materials.append and the frictAngle in Ip2_FrictMat_FrictMat_MindlinPhys. In the Yade document, the frictionAngle means Contact friction angle (in radians), and frictAngle means Instance of MatchMaker determining how to compute interaction’s friction angle.

frictionAngle is a propert of material ("property of particle")

frictAngle tells Ip2 what is the resulting **interaction** friction angle based on two interacting materials.
Using MatchMaker, you can tell Yade to take maximal value, minimal value, average value... depending on your needs.

> 4. In Boxfactory, the meaning of mask is groupMask to apply for newly created spheres. In packs.py[2],the value of mask is 5. I am confused about whether the value mask has the same meaning as the value wallmask in geom.factbox

No.

groupMask determines which particles interact with which.
Using different masks, you can make some groups of particles interact with other group but not interact with a different group.
The given value It is assigned to the resulting particles (you can try something like "for b in O.bodies: print(b.mask)"

wallMask is a condensed (one number) parameter determining which walls should be created and which not

> 5. When RotationEngine is not applied to Boxfactory, the following warning appears at the terminal when emulation begins. Could you give me some advice to deal with it?

Just warnings, no need to bother with it now..

Cheers
Jan

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

Revision history for this message
Mu Wh (muwh-2023) said :
#2

Hi! Jan,
    Thank you very much for your advice and answers. Most problems have been solved according to your answers, but “SyntaxError: invalid syntax” still occurs in terminal after correcte code. Could you give me some advice?
    I have a method that can indirectly realize the rotating falling powders, and I would like to ask you to evaluate whether it is feasible. First,powders are deposited in a facetBox with an opening at the bottom. Then the facetBox is given a RotationEngine and a TranslationEngine(oriented along the z-axis) to achieve the powder factory rotation effect.

The error of corrected code:

Welcome to Yade 20230709-7354~91151dd~focal1
Using python version: 3.8.10 (default, May 26 2023, 14:05:08)
[GCC 9.4.0]
TCP python prompt on localhost:9000, auth cookie `ekycus'
XMLRPC info provider on http://localhost:21000
Running script movingfactory.py
Traceback (most recent call last):
  File "/usr/bin/yadedaily", line 343, in runScript
    execfile(script,globals())
  File "/usr/lib/python3/dist-packages/past/builtins/misc.py", line 86, in execfile
    code = compile(source, filename, "exec")
  File "movingfactory.py", line 15
    FactoryID = BoxFactory(
                       ^
SyntaxError: invalid syntax
[[ ^L clears screen, ^U kills line. F12 controller, F11 3D view (press "h" in 3D view for help), F10 both, F9 generator, F8 plot. ]]

Cheers,
Weihao Mu

Revision history for this message
Best Jan Stránský (honzik) said :
#3

Hi! Jan,
    Thank you very much for your advice and answers. Most problems have been solved according to your answers, but “SyntaxError: invalid syntax” still occurs in terminal after correcte code. Could you give me some advice?

Yes, follow [2] and provide full code.
Here it is clear that the code is the same plus the comma, but it may not be like that always..

Here, O.engines is python list. You cannot have assignments in python lists.
As the error message suggest, you can use FactoryID:=BoxFactory(...), but then it cannot be used as ids in RotationEngine (which should be sequence of numbers)

> ... whether it is feasible.

I did not really get the point here..
Specifically the usage of the factory here..
And the RotationEngine. Should it be used on the spherical particles? Or the cylinder? or ... ?
I would start simply with all (or some) particles created in advance and then make it more complicated with the factory

Cheers
Jan

Revision history for this message
Mu Wh (muwh-2023) said (last edit ):
#5

Hi !
  I’m sorry to trouble you because my code was still having problems a week after I tried to fix it. When I run the code the terminal shows 'BoxFactory' object has no attribute 'id'. I think Boxfactory might not be able to rotate. The code and error are shown below.

  CODE:
from yade import pack, geom

#material
steelID= O.materials.append(FrictMat(density=7800,young=2.2e9,poisson=.3,frictionAngle=math.atan(.62),label="316lsteel"))

#geometry
CylinderID=O.bodies.append(geom.facetCylinder((0,0,10), radius=10, height=20, orientation=Quaternion((1, 0, 0), 0), wire=True,segmentsNumber=60, dynamic=False, wallMask=6, angleRange=None, closeGap=False, radiusBottomInner=-1,material='316lsteel'))

#Engine
O.engines=[
       ForceResetter(),
       InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Cylinder_Aabb()]),
       InteractionLoop(
               [Ig2_Facet_Sphere_ScGeom(),Ig2_Sphere_Sphere_ScGeom()],
               [Ip2_FrictMat_FrictMat_MindlinPhys(en=0.636, es=0.636,frictAngle=math.atan(.62))],
               [Law2_ScGeom_MindlinPhys_Mindlin()]
        ),

           Factory:=BoxFactory(
                maxParticles=2000,
                extents=(3, 3, 3),
                center=(3, 3, 10),
                rMin=0.28,
                rMax=0.29,
                vMin=10,
                vMax=10,
                vAngle=0,
                massFlowRate=10000.,
                normal=(0, 0, -1),
                label='factory',
               materialId=steelID

        ),

        RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=0.1, rotateAroundZero=True, zeroPoint=(0, 0, 10),ids=[Factory.id]),# factory motion
        NewtonIntegrator(gravity=(0,0,-9.81))
]

O.dt=.5e-4*utils.PWaveTimeStep()
O.saveTmp()
O.run()

Error
Welcome to Yade 20230716-7372~493b53a~focal1
Using python version: 3.8.10 (default, May 26 2023, 14:05:08)
[GCC 9.4.0]
TCP python prompt on localhost:9000, auth cookie `aekdsy'
XMLRPC info provider on http://localhost:21000
Running script movingfactory.py
Traceback (most recent call last):
  File "/usr/bin/yadedaily", line 343, in runScript
    execfile(script,globals())
  File "/usr/lib/python3/dist-packages/past/builtins/misc.py", line 87, in execfile
    exec_(code, myglobals, mylocals)
  File "movingfactory.py", line 34, in <module>
    RotationEngine(rotationAxis=(0, 0, 1), angularVelocity=0.1, rotateAroundZero=True, zeroPoint=(0, 0, 10),ids=[Factory.id]),# factory motion
AttributeError: 'BoxFactory' object has no attribute 'id'
[[ ^L clears screen, ^U kills line. F12 controller, F11 3D view (press "h" in 3D view for help), F10 both, F9 generator, F8 plot. ]]
Cheers,
Weihao Mu

Revision history for this message
Mu Wh (muwh-2023) said :
#6

Hi :
    On July 20, 2023, I proposed a method that can indirectly achieve rotating powder fall. However, the engine and factory did not operate as set up. Could you give me some advice? The code is shown below.

 CODE:
from __future__ import print_function
from yade import pack, geom
import time
steelID= O.materials.append(FrictMat(density=7800,young=2.2e9,poisson=.3,frictionAngle=math.atan(.62),label="316lsteel"))
CylinderID=O.bodies.append(geom.facetCylinder((0,0,10), radius=10, height=20, orientation=Quaternion((1, 0, 0), 0), wire=True,segmentsNumber=60, dynamic=False, wallMask=6, angleRange=None, closeGap=False, radiusBottomInner=-1,material='316lsteel'))
BoxID=O.bodies.append(geom.facetBox(( 1.5, 0, 1.5), (1.5, 9.5, 1.5), wallMask=15, wire=False,highlight=False,noBound=False,material='316lsteel'))

O.engines=[
       ForceResetter(),
       InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb(),Bo1_Cylinder_Aabb()]),
       InteractionLoop(
               [Ig2_Facet_Sphere_ScGeom(),Ig2_Sphere_Sphere_ScGeom()],
               [Ip2_FrictMat_FrictMat_MindlinPhys(en=0.636, es=0.636,frictAngle=math.atan(.62))],
               [Law2_ScGeom_MindlinPhys_Mindlin()]
        ),

         BoxFactory(
                maxParticles=2000,
                extents=(2.5, 2.5, 2),
                center=(3, 3, 10),
                rMin=0.28,
                rMax=0.29,
                vMin=10,
                vMax=10,
                vAngle=0,
                massFlowRate=100000.,
                normal=(0, 0, -1),
                label='factory',
               materialId=steelID,
               dead=True

        ),

        HelixEngine(ids=BoxID,rotationAxis=(0,0,1),angularVelocity=0.1,linearVelocity=1,label='helix',dead=True), # factory rotation and translation
        PyRunner(command='timeselect',iterPeriod=1),
        NewtonIntegrator(gravity=(0,0,-9.81))
]

def timeselect():

    if O.iter <= 200000:

       helix.dead=True
       factory.dead=False
       print('\n start to deposite powderds! \n')

    else:

         factory.dead=True
         helix.dead=False
         print('\n start to spread powderds! \n')

O.dt=.5e-4*utils.PWaveTimeStep()
O.saveTmp()
O.run()

Cheers,
Weihao Mu

Revision history for this message
Jan Stránský (honzik) said :
#7

> When I run the code the terminal shows 'BoxFactory' object has no attribute 'id'.

it is because BoxFactory has no attriute id..
You cannot use it like this.

> I think Boxfactory might not be able to rotate.

The factory is just a "meta" object, creating new particles according to given criteria.
You really cannot rotate factory itself..
You can however rotate the particles it creates. But not using BoxFactory itself directly.

> On July 20, 2023, I proposed a method ...
> I have a method that can indirectly realize the rotating falling powders, and I would like to ask you to evaluate whether it is feasible. First,powders are deposited in a facetBox with an opening at the bottom. Then the facetBox is given a RotationEngine and a TranslationEngine(oriented along the z-axis) to achieve the powder factory rotation effect.

Sorry, I missed it
Definitely it is feasible.
I just do not understand what you want to achieve..
What is "powder factory rotation effect"?
Why do you need a factory, and not just simply use predefined set of particles?
Do you want to rotate spheres, or facets?
... ?

> However, the engine and factory did not operate as set up

Most of the time the behavior is exactly as set up.
Maybe it just behaves differently then expected?

Then a valuable information for us would be the expected behavior compared to actual behavior, which is still not clear from the messages (see the questions above).

Cheers
Jan

Revision history for this message
Mu Wh (muwh-2023) said (last edit ):
#8

Hi Jan:
  I wanted to simulate the rotational laying powder process in Additive Manufacturing. My initial idea was to rotate the Boxfactory to achieve the powder laying process, but I had some difficulties with this process. Therefore, I then adopted an indirect powder laying method, that is, first deposit the powder in a facetBox with an open top and bottom surface, and then give the Factbox a HelixEngine to implement the rotating powder laying process,but the engine and factory did not operate as set up. So I'd like to get some advice from you.
Cheers,
Weihao Mu

Revision history for this message
Jan Stránský (honzik) said :
#9

> to simulate the rotational laying powder process in Additive Manufacturing

please describe it more in detail for those who are out of this field (e.g. me).

> Therefore, I then adopted an indirect powder laying method, that is, first deposit the powder in a facetBox

this suggests that you do not need the BoxFactory at all..
Adding another layer to the confusion.

> but the engine and factory did not operate as set up.

As discussed, most likely it operates exactly as set up and most likely it is just the discrepancy between you expectation and how it actually works..
Still, we do not know how it should operate. Without such information we cannot reasonably proceed..
Please, describe your expected simulation properly. E.g.
"I need to deposit spheres in facet cylinder. Spheres are created 10 new spheres every 2 seconds. I need to rotate this and that like this"
Focus on:
- what, when and how should be rotated (I have no idea honestly)
- why do you need BoxFactory

> So I'd like to get some advice from you.

- describe your problem and expectation clearly such that we can help better
- proceed from simple to more complicated. If you have problems with BoxFactory, try first without it

Cheers
Jan

Revision history for this message
Mu Wh (muwh-2023) said (last edit ):
#10