wrap a simulation to a class

Asked by ceguo on 2011-12-20

Hi,

I want to write a class, the __init__() function of which is the set up of a packing, and some other method functions of which include isoConsolidation(), applyStrain(), getStress(), etc. So with this class, I can run a simulation (triaxial, simple shear or any other kind) by directly calling this class and its method functions. Because I want to run several simulations simultaneously within another python code.

First I want to know how to execute a yade file using `python filename` with appropriate libraries imported rather than using `yade filename`? After knowing this, I think I can find out how to write such a wrapped class.

Best regards,
Ning

Question information

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

On 20 December 2011 12:15, ceguo <email address hidden>wrote:

> New question #182459 on Yade:
> https://answers.launchpad.net/yade/+question/182459
>
> Hi,
>
> I want to write a class, the __init__() function of which is the set up of
> a packing, and some other method functions of which include
> isoConsolidation(), applyStrain(), getStress(), etc. So with this class, I
> can run a simulation (triaxial, simple shear or any other kind) by directly
> calling this class and its method functions. Because I want to run several
> simulations simultaneously within another python code.
>
> First I want to know how to execute a yade file using `python filename`
> with appropriate libraries imported rather than using `yade filename`?

Maybe you can try to use the following function:
execfile('fileName.py')

> After knowing this, I think I can find out how to write such a wrapped
> class.
>
> Best regards,
> Ning
>
> --
> 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
>

ceguo (hhh-guo) said : #2

Hi Chiara,

Thanks for your quick reply. But my ultimate goal is to wrap a simulation to a class. Something like:

class triaxialTest():
   def __init__(self):
      self.__O=O
      self.__sp=pack.SpherePack()
      self.__sp.toSimulation()
      self.__stress=[]

   def isoConsolidation(self,pressure):
      self.__O.engines = []
      self.__O.run()
      self.__O.wait()
      self.__stress=[]

   def applyStrain(self, strain):
      self.__O.engines=[]
      self.__O.run()
      self.__O.wait()
      self.__stress=[]

   def getStress(self):
      return self.__stress

   ......

To achieve this, I need to know how these variables (e.g. O) are loaded and from which library.

Ning

>First I want to know how to execute a yade file using `python filename` with appropriate libraries imported rather than using `yade filename`?

"python yade" works perfectly.
Did you have a look at the yade executable itslef? It is a python script, and I think it will answer most of your questions.

ceguo (hhh-guo) said : #4

Hi,

I made the yade library callable from python and now I can run a script using `python test.py`. The script for a biaxial test (first isotropic consolidation then undrained shear) is like this:

from yade.wrapper import *
from yade import *
from yade import pack,plot,utils
from miniEigen import Matrix3

O=Omega()
O.materials.append(FrictMat(young=100e6,poisson=.3,frictionAngle=.5,density=2600))

sp = pack.SpherePack()
sp.makeCloud(minCorner=(0,0,0),maxCorner=(3,3,0),rMean=0.03,rRelFuzz=.25,periodic=True,seed=12345)
sp.toSimulation()
O.cell.hSize = Matrix3(3,0,0, 0,3,0, 0,0,1)
print len(O.bodies)
for p in O.bodies:
   p.state.blockedDOFs = 'zXY'#['z','rx','ry']

#plot.plots={'ey':('sdev',),'sp':('sdev',),'ey_':('ratio',)}
def saveAddData():
   plot.addData(
      stress_xx = biax.stress[0],
      stress_yy = biax.stress[1],
      stress_zz = biax.stress[2],
      strain_xx = biax.strain[0],
      strain_yy = biax.strain[1]
   )
# print O.cell.hSize

O.dt = .5*utils.PWaveTimeStep()

O.engines = [
   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb()]), # detect new collisions
   InteractionLoop(
      [Ig2_Sphere_Sphere_Dem3DofGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
   ),
   Peri3dController(
      goal=(-5.e4,-5.e4,0,0,0,0),
      stressMask=3,
      nSteps=20000,
      doneHook='print "Consolidation finished."; O.pause()',
      maxStrain=.5,
      label='biax'
   ),
   NewtonIntegrator()
]
O.run()
O.wait()

#O.materials.append(FrictMat(young=100e6,poisson=1.,frictionAngle=.5,density=2600))
O.engines = [
   ForceResetter(),
   InsertionSortCollider([Bo1_Sphere_Aabb()]), # detect new collisions
   InteractionLoop(
      [Ig2_Sphere_Sphere_Dem3DofGeom()],
      [Ip2_FrictMat_FrictMat_FrictPhys()],
      [Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
   ),
   Peri3dController(
      goal=(2.e-2,-2.e-2,0,0,0,0),
      stressMask=0,
      nSteps=50000,
      doneHook='print "Shear finished."; O.pause()',
      maxStrain=.5,
      label='biax'
   ),
   NewtonIntegrator(),
   PyRunner(command='saveAddData()',iterPeriod=500)
]
O.run(); O.wait()
plot.saveDataTxt('result.txt',vars=('stress_xx','stress_yy','stress_zz','strain_xx','strain_yy'))
O.exitNoBacktrace()

This works. Now I want to wrap it to a class named simDEM. I wrote like this:

from yade.wrapper import *
from yade import *
from yade import pack,plot,utils
from miniEigen import Matrix3

class simDEM(object):
   def __init__(self):
      self.__O=Omega()
      self.__O.materials.append(FrictMat(young=1.e8,poisson=.3,frictionAngle=.5,density=2600))
      self.__sp=pack.SpherePack()
      self.__sp.makeCloud(minCorner=(0,0,0),maxCorner=(3,3,0),rMean=.03,rRelFuzz=.25,periodic=True,seed=12345)
      self.__sp.toSimulation()
      self.__O.cell.hSize=Matrix3(3,0,0, 0,3,0, 0,0,1)
      for p in self.__O.bodies:
         p.state.blockedDOFs='zXY'
      self.__O.dt=.5*utils.PWaveTimeStep()

   def countParticle(self):
      return len(self.__O.bodies)

   def saveAddData(self):
      plot.addData(
         stress_xx = biax.stress[0],
         stress_yy = biax.stress[1],
         stress_zz = biax.stress[2],
         strain_xx = biax.strain[0],
         strain_yy = biax.strain[1]
      )

   def consolidation(self, stress=-5.e4):
      self.__O.eigines=[
         ForceResetter(),
         InsertionSortCollider([Bo1_Sphere_Aabb()]),
         InteractionLoop(
            [Ig2_Sphere_Sphere_Dem3DofGeom()],
            [Ip2_FrictMat_FrictMat_FrictPhys()],
            [Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
         ),
         Peri3dController(
            goal=(stress,stress,0,0,0,0),
            stressMask=3,
            nSteps=20000,
            doneHook='print "Consolidation finished!"; self.__O.pause()',
            maxStrain=.5,
            label='biax'
         ),
         NewtonIntegrator()
      ]
      self.__O.run(20000,True)

   def shear(self, strain=-1.e-2):
      self.__O.eigines=[
         ForceResetter(),
         InsertionSortCollider([Bo1_Sphere_Aabb()]),
         InteractionLoop(
            [Ig2_Sphere_Sphere_Dem3DofGeom()],
            [Ip2_FrictMat_FrictMat_FrictPhys()],
            [Law2_Dem3DofGeom_FrictPhys_CundallStrack()]
         ),
         Peri3dController(
            goal=(-1.*strain,strain,0,0,0,0),
            stressMask=0,
            nSteps=50000,
            doneHook='print "Shear finished!"; self.__O.pause()',
            maxStrain=.5,
            label='biax'
         ),
         NewtonIntegrator(),
         PyRunner(command='self.saveAddData()',iterPeriod=500)
      ]
      self.__O.run(50000,True)

   def outputResult(self):
      plot.saveDataTxt(
         'result.txt',
         vars=('stress_xx','stress_yy','stress_zz','strain_xx','strain_yy')
      )

   def finalization(self):
      self.__O.exitNoBacktrace()

This doesn't work smoothly within the function consolidation. But it's very close to what I want. I hope anyone who's more familiar with the code can help me to modify it. Below is what I got:

$ python
>>> from multiscaleDEM import simDEM
>>> a = simDEM()
>>> a.countParticle()
1342
>>> a.consolidation() # no response, doneHook not executed!
>>> a.shear() # no response, doneHook not executed! Neither PyRunner()
>>> a.outputResult()
Error! vars=('stress_xx','stress_yy','stress_zz','strain_xx','strain_yy')
            plot.py in saveDataTxt for i in range(len(data[vars[0]])):
            KeyError: 'stress_xx'

Launchpad Janitor (janitor) said : #5

This question was expired because it remained in the 'Open' state without activity for the last 15 days.

Hi ceguo,
Did you progress on your problem? For me it was not clear if the last error was due to the initial wrapping question or just to a command that would fail even in a standard script (guessing the latest).
Note the typo:
self.__O.eigines=[

ceguo (hhh-guo) said : #7

Hi Chareyre,

Sorry for the delayed reply. I'm just back from the Chinese New Year Holiday.
After I corrected the typo, there is error when I executed `a.consolidation()` instead of without response:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'Omega' is not defined

It seems there is problem within the engine (especially in `Peri3dController` because doneHook and PyRunner call other functions). So can I run a compression/shear test without using the engine? e.g. one command by one command...

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

Hi Ning,

I tried something similar some time ago and somehow I succeeded, but I
dont remember how exactly :-) could you please send me your script(s) so
I can try to find the problem?

In my case it was something like Omega was in some file without
yade.wrapper which resulted in this type of error..

Jan

ceguo píše v Po 30. 01. 2012 v 08:01 +0000:
> Question #182459 on Yade changed:
> https://answers.launchpad.net/yade/+question/182459
>
> Status: Expired => Open
>
> ceguo is still having a problem:
> Hi Chareyre,
>
> Sorry for the delayed reply. I'm just back from the Chinese New Year Holiday.
> After I corrected the typo, there is error when I executed `a.consolidation()` instead of without response:
>
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> NameError: name 'Omega' is not defined
>
> It seems there is problem within the engine (especially in
> `Peri3dController` because doneHook and PyRunner call other functions).
> So can I run a compression/shear test without using the engine? e.g. one
> command by one command...
>

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

Peri3dController has doneHook set to O.pause() by default in r3011, so
you can try the script with none doneHooke specified, let us know if it
hepled.

Jan

ceguo píše v Po 30. 01. 2012 v 08:01 +0000:
> Question #182459 on Yade changed:
> https://answers.launchpad.net/yade/+question/182459
>
> Status: Expired => Open
>
> ceguo is still having a problem:
> Hi Chareyre,
>
> Sorry for the delayed reply. I'm just back from the Chinese New Year Holiday.
> After I corrected the typo, there is error when I executed `a.consolidation()` instead of without response:
>
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> NameError: name 'Omega' is not defined
>
> It seems there is problem within the engine (especially in
> `Peri3dController` because doneHook and PyRunner call other functions).
> So can I run a compression/shear test without using the engine? e.g. one
> command by one command...
>

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

Hi Ning,

try r3015, NameError should not appear..

Jan

ceguo píše v Po 30. 01. 2012 v 08:01 +0000:
> Question #182459 on Yade changed:
> https://answers.launchpad.net/yade/+question/182459
>
> Status: Expired => Open
>
> ceguo is still having a problem:
> Hi Chareyre,
>
> Sorry for the delayed reply. I'm just back from the Chinese New Year Holiday.
> After I corrected the typo, there is error when I executed `a.consolidation()` instead of without response:
>
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> NameError: name 'Omega' is not defined
>
> It seems there is problem within the engine (especially in
> `Peri3dController` because doneHook and PyRunner call other functions).
> So can I run a compression/shear test without using the engine? e.g. one
> command by one command...
>

ceguo (hhh-guo) said : #11

Thanks Jan,

r3015 solves the problem of NameError.
Another thing is how can we export the results stored in `biax` in this case, as I find we cannot use PyRunner to execute saveAddData(). Or how can we get stress, strain, fabric tensors which may be used further in the simulation?

Regards,
Ning

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

Hi Ning,

The problem is that PyRunner calls functions in global namespace, so
variable self is not defined. I found this workaround - in shear
function do following:

   def shear(self, strain=-1.e-2):
      import __builtin__
      __builtin__.__dict__['saveAddData'] = self.saveAddData
      self.__O.engines=[
         ...
         PyRunner(command='saveAddData()',iterPeriod=500)
      ]

This approach should work. You can also try something with 'global'
statement or globals() dictionary.

Good luck and let us know if it works or not :-)

Jan

ceguo píše v Čt 02. 02. 2012 v 14:20 +0000:
> Question #182459 on Yade changed:
> https://answers.launchpad.net/yade/+question/182459
>
> Status: Answered => Open
>
> ceguo is still having a problem:
> Thanks Jan,
>
> r3015 solves the problem of NameError.
> Another thing is how can we export the results stored in `biax` in this case, as I find we cannot use PyRunner to execute saveAddData(). Or how can we get stress, strain, fabric tensors which may be used further in the simulation?
>
> Regards,
> Ning
>

ceguo (hhh-guo) said : #13

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

It works, apparently. ;)