Changing the material while running

Asked by Shenyang Cai

Hi all!

I want to change the material of certain spheres while running the program, and here is my script:

from yade import pack

frict=O.materials.append(FrictMat(young=1e6,
                                   poisson=0.3,
                                   density=2600))
con=O.materials.append(CpmMat(young=1e6,
                                 poisson=0.3,
                                 epsCrackOnset=0.1,
                                 relDuctility=0,
                                 density=2600))

floor=utils.wall(position=(0,0,0), axis=2, material=frict)
O.bodies.append(floor)

sp1=pack.SpherePack()
sp1.makeCloud((-0.5,-0.5,1),(0.5,0.5,2),rMean=0.05,rRelFuzz=0.2)
m = sp1.toSimulation(material=con) #defining the lower cube of spheres

sp2=pack.SpherePack()
sp2.makeCloud((-0.25,-0.5,3),(0.75,0.5,4),rMean=0.05,rRelFuzz=0.2)
n = sp2.toSimulation(material=con) #defining the upper cube of spheres

for i in m:
    O.bodies[i].shape.color = (1,1,1)

O.engines=[ForceResetter(),
           InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=1.7), Bo1_Wall_Aabb()]),
           InteractionLoop(
               [Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=1.7), Ig2_Wall_Sphere_ScGeom()],
               [Ip2_CpmMat_CpmMat_CpmPhys(), Ip2_FrictMat_CpmMat_FrictPhys()],
               [Law2_ScGeom_CpmPhys_Cpm(), Law2_ScGeom_FrictPhys_CundallStrack()]
               ),
           NewtonIntegrator(damping=0.3, gravity=(0,0,-9.81)),
           PyRunner(command = "change()", iterPeriod = 300,label = "checker")
           ]
O.dt=0.5*utils.PWaveTimeStep()

def change():
    for i in n:
        if O.bodies[n].state.pos[2] <= 1: #when two cubes collide
            for i in n:
                O.bodies[n].material.label = frict #here I want to change the upper cube's material from CpmMat to FrictMat
            checher.command = "done()"
            return

def done():
    return

The error message is:
ArgumentError Traceback (most recent call last)
/usr/bin/yadedaily in <module>()

/usr/bin/yadedaily in change()
     38 def change():
     39 for i in n:
---> 40 if O.bodies[n].state.pos[2] <= 1:
     41 for i in n:
     42 O.bodies[n].material.label = frict

ArgumentError: Python argument types in
    BodyContainer.__getitem__(BodyContainer, list)
did not match C++ signature:
    __getitem__(pyBodyContainer {lvalue}, int)

I am wondering whether an object's material can be changed while the program is running .
Thanks!

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
Hongyang Cheng (alex-cheng) said :
#1

Hi,

I don't know how to do it while running the simulation if you are referring to change material types. But you could export the geometry of your "upper cube" then start over with newly defined material types. For how to change material constants, you might want to take a look at https://answers.launchpad.net/yade/+question/238797.

BTW to fix the error message, try
def change():
    for b in O.bodies:
        if b.state.pos[2] <= 1:
             b.mat.label = 'something' # this will not change the material type

alex

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

Hello,

changing the matrial is of particles is as easy as

b = O.bodies[someID]
b.mat = someOtherMaterialInstance # b.material = ... also works

but be careful, that change of material have NO effect on already existing
interactions!

The error you get is because of python types (as the error message says).
You can try O.bodies[i] instead of O.bodies[n]:

def change():
    for i in n:
        if O.bodies[i].state.pos[2] <= 1:# should be O.bodies[i] instead of
O.bodies[n]???
            #for i in n: # Why this second loop?
                O.bodies[i].material = O.materials[frict] # As suggested by
Alex, assign material directly, not its label
                ...

cheers
Jan

2015-03-17 13:21 GMT+01:00 Shenyang Cai <
<email address hidden>>:

> New question #263780 on Yade:
> https://answers.launchpad.net/yade/+question/263780
>
> Hi all!
>
> I want to change the material of certain spheres while running the
> program, and here is my script:
>
>
> from yade import pack
>
> frict=O.materials.append(FrictMat(young=1e6,
> poisson=0.3,
> density=2600))
> con=O.materials.append(CpmMat(young=1e6,
> poisson=0.3,
> epsCrackOnset=0.1,
> relDuctility=0,
> density=2600))
>
> floor=utils.wall(position=(0,0,0), axis=2, material=frict)
> O.bodies.append(floor)
>
> sp1=pack.SpherePack()
> sp1.makeCloud((-0.5,-0.5,1),(0.5,0.5,2),rMean=0.05,rRelFuzz=0.2)
> m = sp1.toSimulation(material=con) #defining the lower cube of spheres
>
> sp2=pack.SpherePack()
> sp2.makeCloud((-0.25,-0.5,3),(0.75,0.5,4),rMean=0.05,rRelFuzz=0.2)
> n = sp2.toSimulation(material=con) #defining the upper cube of spheres
>
> for i in m:
> O.bodies[i].shape.color = (1,1,1)
>
> O.engines=[ForceResetter(),
> InsertionSortCollider([Bo1_Sphere_Aabb(aabbEnlargeFactor=1.7),
> Bo1_Wall_Aabb()]),
> InteractionLoop(
> [Ig2_Sphere_Sphere_ScGeom(interactionDetectionFactor=1.7),
> Ig2_Wall_Sphere_ScGeom()],
> [Ip2_CpmMat_CpmMat_CpmPhys(),
> Ip2_FrictMat_CpmMat_FrictPhys()],
> [Law2_ScGeom_CpmPhys_Cpm(),
> Law2_ScGeom_FrictPhys_CundallStrack()]
> ),
> NewtonIntegrator(damping=0.3, gravity=(0,0,-9.81)),
> PyRunner(command = "change()", iterPeriod = 300,label =
> "checker")
> ]
> O.dt=0.5*utils.PWaveTimeStep()
>
> def change():
> for i in n:
> if O.bodies[n].state.pos[2] <= 1: #when two cubes collide
> for i in n:
> O.bodies[n].material.label = frict #here I want to change
> the upper cube's material from CpmMat to FrictMat
> checher.command = "done()"
> return
>
> def done():
> return
>
>
>
>
> The error message is:
> ArgumentError Traceback (most recent call last)
> /usr/bin/yadedaily in <module>()
>
> /usr/bin/yadedaily in change()
> 38 def change():
> 39 for i in n:
> ---> 40 if O.bodies[n].state.pos[2] <= 1:
> 41 for i in n:
> 42 O.bodies[n].material.label = frict
>
> ArgumentError: Python argument types in
> BodyContainer.__getitem__(BodyContainer, list)
> did not match C++ signature:
> __getitem__(pyBodyContainer {lvalue}, int)
>
> I am wondering whether an object's material can be changed while the
> program is running .
> Thanks!
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
Shenyang Cai (sycai) said :
#3

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

Revision history for this message
Shenyang Cai (sycai) said :
#4

Hongyang thanks for your answer too, the link you gave is of great help!