memory leaks when instantiating an engine

Asked by Zhang Wenyue

Hi,

I'm also doing some work related to the removal of particles, and I have a problem similar to Question #452277.
https://answers.launchpad.net/yade/+question/452277

 I tried to set the flowEngine.dead=1 and then set it to 0 after few steps, which didn't work. I tried to slice the list of engines to instantiate the flowEngine, which led to memory leak. Do anyone have a way to release the memory effectively?

Can anyone give me some suggestion? Thanks a lot.
I'm running Yade 2018.02b, Ubuntu 18.04.

My code is shown as follow:
=============================================

from yade import pack,qt,plot

num_spheres=1000# number of spheres
young=1e6
compFricDegree = 3 # initial contact friction during the confining phase
finalFricDegree = 30 # contact friction during the deviatoric loading
mn,mx=Vector3(0,0,0),Vector3(2,2,6) # corners of the initial packing
flag=1
flag2=0

O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=radians(compFricDegree),density=2600,label='spheres'))
O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
walls=aabbWalls([mn,mx],thickness=0,material='walls')
wallIds=O.bodies.append(walls)

sp=pack.SpherePack()
sp.makeCloud(mn,mx,rMean=0.3,rRelFuzz=0,num=50,periodic=False)
sp.makeCloud(mn,mx,rMean=0.03,rRelFuzz=0,num=1000,periodic=False)
sp.toSimulation(material='spheres')

triax=TriaxialStressController(
 thickness = 0,
 stressMask = 7,
 max_vel = 0.005,
 internalCompaction=0, # If true the confining pressure is generated by growing particles
# wall_bottom_activated=False
)

newton=NewtonIntegrator(damping=0.2)

O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb()]),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
  [Ip2_FrictMat_FrictMat_FrictPhys()],
  [Law2_ScGeom_FrictPhys_CundallStrack()],label="iloop"
 ),
 FlowEngine(dead=1,label="flow"),#introduced as a dead engine for the moment, see 2nd section
 GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.8),
 triax,
 newton,
]

triax.goal1=triax.goal2=triax.goal3=-10000

while 1:
  O.run(1000,1)
  unb=unbalancedForce()
  if unb<0.001 and abs(-10000-triax.meanStress)/10000<0.001:
    break

setContactFriction(radians(finalFricDegree))

## ______________ Oedometer section _________________

triax.stressMask=7
triax.goal1=triax.goal2=triax.goal3=-10000

#B. Activate flow engine and set boundary conditions in order to get permeability

flow.dead=0
flow.defTolerance=0.3
flow.meshUpdateInterval=100
flow.useSolver=3
flow.permeabilityFactor=1
flow.viscosity=10
flow.bndCondIsPressure=[0,0,0,0,1,1]
flow.bndCondValue=[0,0,0,0,100,0]
flow.boundaryUseMaxMin=[0,0,0,0,0,0]
O.dt=0.1e-4
O.dynDt=False

newton.damping=0
triax.wall_back_activated=0
O.engines=O.engines+[PyRunner(command='addPlotData()',iterPeriod=100),]
O.engines=O.engines+[PyRunner(command='erosion()',iterPeriod=100),]

def erosion():
    global flag
    global flag2
    k=0
    if flag:
        for i in O.interactions:
            if i.id1==5:
                if i.id2>5 and O.bodies[i.id2].shape.radius<0.1:
                    k=i.id2
                    O.interactions.erase(i.id1, i.id2)
                    O.bodies.erase(k)
                    flag2=1
            if i.id2==5:
                if i.id1>5 and O.bodies[i.id1].shape.radius<0.1:
                    k=i.id1
                    O.interactions.erase(i.id1, i.id2)
                    O.bodies.erase(k)
                    flag2=1
        if flag2:
            flag=0
            O.pause()
            O.engines=O.engines[0:3]+O.engines[4:]
            O.step()
            O.step()
            O.engines=O.engines[0:3]+[FlowEngine(dead=0,label="flow"),]+O.engines[3:]
            flow.defTolerance = 0.3
            flow.meshUpdateInterval = 100
            flow.useSolver = 3
            flow.permeabilityFactor = 1
            flow.viscosity = 10
            flow.bndCondIsPressure = [0, 0, 0, 0, 1, 1]
            flow.bndCondValue = [0, 0, 0, 0, 100, 0]
            flow.boundaryUseMaxMin = [0, 0, 0, 0, 0, 0]
            O.dt = 0.1e-4
            O.dynDt = False
            O.step()
            O.step()
            O.step()
            flag=1
            O.run()
=============================================

Best,
Zhang Wenyue

Question information

Language:
English Edit question
Status:
Answered
For:
Yade Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Chareyre (bruno-chareyre-9) said :
#1

Hi, if i read correctly you are adding one more engine to O.engines every
100 iterations. Memory has to grow then, this in not a memory leak. The
question is more: does it make sense to accumulate engines? The answer is:
no. :)

Le dim. 15 juil. 2018 14:47, Zhang Wenyue <
<email address hidden>> a écrit :

> New question #670889 on Yade:
> https://answers.launchpad.net/yade/+question/670889
>
> Hi,
>
> I'm also doing some work related to the removal of particles, and I have a
> problem similar to Question #452277.
> https://answers.launchpad.net/yade/+question/452277
>
> I tried to set the flowEngine.dead=1 and then set it to 0 after few
> steps, which didn't work. I tried to slice the list of engines to
> instantiate the flowEngine, which led to memory leak. Do anyone have a way
> to release the memory effectively?
>
> Can anyone give me some suggestion? Thanks a lot.
> I'm running Yade 2018.02b, Ubuntu 18.04.
>
> My code is shown as follow:
> =============================================
>
> from yade import pack,qt,plot
>
> num_spheres=1000# number of spheres
> young=1e6
> compFricDegree = 3 # initial contact friction during the confining phase
> finalFricDegree = 30 # contact friction during the deviatoric loading
> mn,mx=Vector3(0,0,0),Vector3(2,2,6) # corners of the initial packing
> flag=1
> flag2=0
>
>
> O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=radians(compFricDegree),density=2600,label='spheres'))
>
> O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
> walls=aabbWalls([mn,mx],thickness=0,material='walls')
> wallIds=O.bodies.append(walls)
>
> sp=pack.SpherePack()
> sp.makeCloud(mn,mx,rMean=0.3,rRelFuzz=0,num=50,periodic=False)
> sp.makeCloud(mn,mx,rMean=0.03,rRelFuzz=0,num=1000,periodic=False)
> sp.toSimulation(material='spheres')
>
> triax=TriaxialStressController(
> thickness = 0,
> stressMask = 7,
> max_vel = 0.005,
> internalCompaction=0, # If true the confining pressure is
> generated by growing particles
> # wall_bottom_activated=False
> )
>
> newton=NewtonIntegrator(damping=0.2)
>
> O.engines=[
> ForceResetter(),
> InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb()]),
> InteractionLoop(
> [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
> [Ip2_FrictMat_FrictMat_FrictPhys()],
> [Law2_ScGeom_FrictPhys_CundallStrack()],label="iloop"
> ),
> FlowEngine(dead=1,label="flow"),#introduced as a dead engine for
> the moment, see 2nd section
>
> GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.8),
> triax,
> newton,
> ]
>
> triax.goal1=triax.goal2=triax.goal3=-10000
>
> while 1:
> O.run(1000,1)
> unb=unbalancedForce()
> if unb<0.001 and abs(-10000-triax.meanStress)/10000<0.001:
> break
>
> setContactFriction(radians(finalFricDegree))
>
> ## ______________ Oedometer section _________________
>
> triax.stressMask=7
> triax.goal1=triax.goal2=triax.goal3=-10000
>
> #B. Activate flow engine and set boundary conditions in order to get
> permeability
>
> flow.dead=0
> flow.defTolerance=0.3
> flow.meshUpdateInterval=100
> flow.useSolver=3
> flow.permeabilityFactor=1
> flow.viscosity=10
> flow.bndCondIsPressure=[0,0,0,0,1,1]
> flow.bndCondValue=[0,0,0,0,100,0]
> flow.boundaryUseMaxMin=[0,0,0,0,0,0]
> O.dt=0.1e-4
> O.dynDt=False
>
> newton.damping=0
> triax.wall_back_activated=0
> O.engines=O.engines+[PyRunner(command='addPlotData()',iterPeriod=100),]
> O.engines=O.engines+[PyRunner(command='erosion()',iterPeriod=100),]
>
> def erosion():
> global flag
> global flag2
> k=0
> if flag:
> for i in O.interactions:
> if i.id1==5:
> if i.id2>5 and O.bodies[i.id2].shape.radius<0.1:
> k=i.id2
> O.interactions.erase(i.id1, i.id2)
> O.bodies.erase(k)
> flag2=1
> if i.id2==5:
> if i.id1>5 and O.bodies[i.id1].shape.radius<0.1:
> k=i.id1
> O.interactions.erase(i.id1, i.id2)
> O.bodies.erase(k)
> flag2=1
> if flag2:
> flag=0
> O.pause()
> O.engines=O.engines[0:3]+O.engines[4:]
> O.step()
> O.step()
>
> O.engines=O.engines[0:3]+[FlowEngine(dead=0,label="flow"),]+O.engines[3:]
> flow.defTolerance = 0.3
> flow.meshUpdateInterval = 100
> flow.useSolver = 3
> flow.permeabilityFactor = 1
> flow.viscosity = 10
> flow.bndCondIsPressure = [0, 0, 0, 0, 1, 1]
> flow.bndCondValue = [0, 0, 0, 0, 100, 0]
> flow.boundaryUseMaxMin = [0, 0, 0, 0, 0, 0]
> O.dt = 0.1e-4
> O.dynDt = False
> O.step()
> O.step()
> O.step()
> flag=1
> O.run()
> =============================================
>
> Best,
> Zhang Wenyue
>
> --
> You received this question notification because your team yade-users 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
Zhang Wenyue (zhangwenyue) said :
#2

Dear, Chareyre

Yes, so the problem is how to delete the old one and free the memory. By Antoine in Question #452277, "del flow" is not effective. I need to instantiate the engine frequently so I can't follow the method of saving and reloading.

Best,
Wenyue

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#3

Hi, following #452277 the solution is to implement a "reset" function in the engine itself to handle changes in the list of bodies. It can be implemented on the c++ side if you have the patience to do it.
Bruno

Can you help with this problem?

Provide an answer of your own, or ask Zhang Wenyue for more information if necessary.

To post a message you must log in.