# Problem with the combined engine

Hi,

I'm new with Yade, and I have problem with combined engine. I want to change the translationAxis and the velocity after a few iterations but I still have an issue about the global variables.
Could you help me?

#!/usr/bin/python
# -*- coding: utf-8 -*-

from __future__ import print_function
from builtins import range
import random

## PhysicalParameters

## Import geometry
rod = O.bodies.append(ymport.stl('tool.stl',wire=False,color=[0.31,0.47,0.47]))

# Plate dimension
thickness = 1.0 # cm
width = 5.0 # cm
length = 11.0 # cm
boxMax = (2,2.5,0)

# Spheres
#nbSpheres = (ndiv_x,ndiv_y,ndiv_z)
nbSpheres = (40,40,10)#(110,50,10)
print("Creating %d spheres..."%(nbSpheres[0]*nbSpheres[1]*nbSpheres[2]), end=' ')
for i in range(nbSpheres[0]):
for j in range(nbSpheres[1]):
for k in range(nbSpheres[2]):
fixed = False
color=[0.21,0.22,0.1]
if (i==0 or i==nbSpheres[0]-1 or k==nbSpheres[2]-1 or j==0 or j==nbSpheres[1]-1):
fixed = True
color=[0.21,0.22,0.3]
O.bodies.append(sphere([x,y,z],r,color=color,fixed=fixed))
print("done\n")

## Estimate time step
#O.dt=PWaveTimeStep()
O.dt=0.0001

def updateParameters():
aTime = (O.iter*O.dt)
if aTime>0.005: # fist part
velVec = Vector3(-1,0,0)
tranVel = 1.0
transEngine.translationAxis = velVec
transEngine.velocity = tranVel

## Engines
O.engines=[
ForceResetter(), # 0
InsertionSortCollider([ # 1
Bo1_Sphere_Aabb(),
Bo1_Facet_Aabb(),
]),
InteractionLoop( # 2
[Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
[Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_ScGeom_FrictPhys_CundallStrack()]
),
CombinedKinematicEngine(ids=rod,label='combEngine') + TranslationEngine(translationAxis=(0,0,-1),velocity=0.6) + RotationEngine(rotationAxis=(0,0,-1), angularVelocity=20, rotateAroundZero=True, zeroPoint=(0,0,0)),
NewtonIntegrator(damping=2.0,gravity=[0,0,-9.81]), # 3
PyRunner(iterPeriod=1, command='updateParameters()'),
# save data from Yade's own 3d view
#qt.SnapshotEngine(fileBase='3d-',iterPeriod=1,label='snapshot'),
#PyRunner(command='finish()',iterPeriod=10)
]

import sys,time

print("Start simulation: ")
nbIter=60

v=qt.View()

O.stopAtIter=nbIter
O.run()

# this function is called when the simulation is finished
def finish():
# snapshot is label of qt.SnapshotEngine
# the 'snapshots' attribute contains list of all saved files
makeVideo(snapshot.snapshots,'3d.mpeg',fps=1,bps=10)
O.pause()

#for t in xrange(2):
# start=time.time();O.run(nbIter);O.wait();finish=time.time()
# speed=nbIter/(finish-start); print '%g iter/sec\n'%speed
#print "FINISH"
#quit()

BR
Przemek

## Question information

Language:
English Edit question
Status:
For:
Assignee:
No assignee Edit question
Last query:
2019-11-15
2019-11-15
 Jérôme Duriez (jduriez) said on 2019-11-15: #1

What is your "issue about the global variables" ? (the error message)

 Jan Stránský (honzik) said on 2019-11-15: #2

Hello,

welcome :-)

> I still have an issue about the global variables

- to be more specific (like including the error message in the question)
- include a MWE (W=working). If external files (like too.stl file) is involved, try to include it in the question, or preferably not use it and e.g. create a few facets manually instead (if the problem is not related to the stl file). Without it, we cannot try the code ourselves..

I guess the problem is that transEngine is not defined in updateParameters() function. You call it, but you do not define it anywhere in the script and Python interpreter has no clue what it is..

Try one of these:

a) set label to TranslationEngine when it is created
... TranslationEngine(..., label='transEngine')

b) create TranslationEngine before O.engines and then add the instance to CombinedKinematicEngine
transEngine = TranslationEngine(...)
O.engines = [
...
CombinedKinematicEngine(...) + transEngine + ...

c) define transEngine in updateParameters() from combEngine content
transEngine = combEngine.comb[0]
transEngine.translationAxis = velVec
transEngine.velocity = tranVel

cheers
Jan

 Przemek (przemekn) said on 2019-11-15: #3

Sorry, next time I'll adjust to guidelines.

Here is the error:

UnboundLocalError Traceback (most recent call last)

52 tranVel = 1.0
53 transEngine = combEngine.comb[0]
---> 54 transEngine.translationAxis = velVec
55 transEngine.velocity = tranVel
56

UnboundLocalError: local variable 'velVec' referenced before assignment

I tried to modify the script by yous suggestions but it still doesn't work.

 Jan Stránský (honzik) said on 2019-11-15: #4

Hello,

velVec is assigned a value inside an if condition (if aTime>0.005).
This condition is false (you can easily check, O.dt=0.0001, iterPeriod=1) and velVec therefore has no value.
Then you try to assign it to translation engine, but it is currently just nothing, so Python comes with this error.

cheers
Jan

PPS: aTime = (O.iter*O.dt) ... you can use directly aTime = O.time

 Przemek (przemekn) said on 2019-11-15: #5

Hi,

now it's working :) Thanks a lot!