the bugs in my scripts of layer sample pareparing code

Asked by ting

Hi All:

Right now i am doing some simulation based on the following: (i am doing the same job as Nima Goudarzi mentioned)
As a part of a trixal test with my own implemented model in YADE, I need to compact my sample in the vertical direction to reach to a target void ratio. Dimensions of the sample are 3.5*3.5mm*7.1mm and it will be confined in six frictionless walls. The method of compaction is UCM and the sample will be compacted in 5 layers. As I am going to produce 100000 particles (based on a PSD), I may assume that each layer has 2000 spheres in it. Here is the sequence of compacting:
1- First layer is deposited and then compacted to a target void ratio of 0.73.
2- After depositing the second layer on top of the first layer, both layers will be compacted to reach a target void ratio of 0.71.
3- After depositing the third layer on top of the second layer, all three layers will be compacted to reach a target void ratio of 0.69.
4- After depositing the fourth layer on top of the third layer, all four layers will be compacted to reach a target void ratio of 0.67.
5- After depositing the fifth layer on top of the fourth layer, all five layers will be compacted to reach a target void ratio of 0.65.
This 0.65 is the target void ratio for the whole assembly.

the following is the code:

# -*- coding: utf-8 -*-
############################################
### DEFINING VARIABLES AND MATERIALS ###
############################################

# The following 5 lines will be used later for batch execution
nRead=readParamsFromTable(
 num_spheres=2000,# number of spheres
 compFricDegree = 30, # contact friction during the confining phase
 key='_triax_base_', # put simulation's name here
 unknownOk=True
)
############################################
from yade.params import table
a = [1,2,3,4,5]
b = [1]
c = [5]
psdSizes,psdCumm=[.1,.13,.16,.19,.22,.26,.31],[0.,0.01,0.05,0.25,.6,.92,1.]
for t in a:
 num_spheres=table.num_spheres*t# number of spheres
 key=table.key

 compFricDegree = table.compFricDegree # initial contact friction during the confining phase (will be decreased during the REFD compaction process)
 finalFricDegree = 30 # contact friction during the deviatoric loading
 rate=-0.02 # loading rate (strain rate)
 damp=0.7 # damping coefficient
 stabilityThreshold=0.01 # we test unbalancedForce against this value in different loops
 young=100000000 # contact stiffness

 mn,mx=Vector3(0,0,(7.1/5)*(t-1)),Vector3(3.5,3.5,(7.1/5)*t) # corners of the initial packing
 targetPorosity = (0.73-0.02*(t-1))/(1+0.73-0.02*(t-1)) #the porosity we want for the packing (just for testing)

 ## create materials for spheres and plates
 O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=radians(compFricDegree),density=2600,label='spheres')) #material for the spheres
 O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls')) #material for the wall

 ## create walls around the packing
 walls=aabbWalls([mn,mx],thickness=0,material='walls')
 wallIds=O.bodies.append(walls)

 while t > b:
  O.bodies.erase(4) #delect the rigid plate in the bottom

 ## use a SpherePack object to generate a random loose particles packing
 sp=pack.SpherePack()
 sp.makeCloud(mn,mx,-1,num_spheres,psdSizes=psdSizes,psdCumm=psdCumm)

 O.bodies.append([sphere(center,rad,material='spheres') for center,rad in sp])
 #or alternatively (higher level function doing exactly the same):
 #sp.toSimulation(material='spheres')

 ############################
 ### DEFINING ENGINES ###
 ############################

 triax=TriaxialStressController(
 ## TriaxialStressController will be used to control stress and strain. It controls particles size and plates positions.

 maxMultiplier=1.+2e4/young, # spheres growing factor (fast growth)
 finalMaxMultiplier=1.+2e3/young, # spheres growing factor (slow growth)
 thickness = 0,
 ## switch stress/strain control using a bitmask.
 ## Say x=1 if stess is controlled on x, else x=0. Same for for y and z, which are 1 or 0.
 ## Then an integer uniquely defining the combination of all these tests is: mask = x*1 + y*2 + z*4
 ## to put it differently, the mask is the integer whose binary representation is xyz, i.e.
 ## "100" (1) means "x", "110" (3) means "x and y", "111" (7) means "x and y and z", etc.
 stressMask = 7,
 internalCompaction=True, # If true the confining pressure is generated by growing particles
 )

 newton=NewtonIntegrator(damping=damp)

 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()]
 ),

 GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.8),
 triax,
 TriaxialStateRecorder(iterPeriod=100,file='WallStresses'+table.key),
 newton
 ]

 #Display spheres with 2 colors for seeing rotations better
 #Gl1_Sphere.stripes=0
 #if nRead==0: yade.qt.Controller(), yade.qt.View()

 ####################################################
 ### APPLYING Z direction PRESSURE for porosity ##
 ####################################################

 #the value of (isotropic) confining stress defines the target stress to be applied in Z directions
 triax.goal2=-50000
 while 1:
  O.run(1000, True)
  ##the global unbalanced force on dynamic bodies, thus excluding boundaries, which are not at equilibrium
  unb=unbalancedForce()
  print 'unbalanced force:',unb,' mean stress: ',triax.meanStress
  if unb<stabilityThreshold and abs(-50000/3-triax.meanStress)/(50000/3)<0.001:
    break

 #O.save('confinedState'+key+'.yade.gz')
 print "### Compression state saved ###"

 ###################################################
 ### REACHING A SPECIFIED POROSITY PRECISELY ###
 ###################################################

 ### We will reach a prescribed value of porosity with the REFD algorithm

 import sys #this is only for the flush() below
 while triax.porosity>targetPorosity:
 ## we decrease friction value and apply it to all the bodies and contacts
 compFricDegree = 0.85*compFricDegree
 setContactFriction(radians(compFricDegree))
 print "\r Friction: ",compFricDegree," porosity:",triax.porosity,
 sys.stdout.flush()
 ## while we run steps, triax will tend to grow particles as the packing
 ## keeps shrinking as a consequence of decreasing friction. Consequently
 ## porosity will decrease
 O.run(500,1)

 while t < c:
 O.bodies.erase(5) #delect the wall in the positive direction of Z
 O.save('compactedState'+key+'.yade.gz')
 print (targetPorosity)
 print "### Compacted state saved ###"

O.bodies.append([sphere(center,rad,material='spheres') for center,rad in sp])

#########################################################
### APPLYING CONFINING PRESSURE for triaxial test ####
#########################################################

#the value of (isotropic) confining stress defines the target stress to be applied in all three directions
triax.goal1=triax.goal2=triax.goal3=-5000

while 1:
  O.run(1000, True)
  ##the global unbalanced force on dynamic bodies, thus excluding boundaries, which are not at equilibrium
  unb=unbalancedForce()
  print 'unbalanced force:',unb,' mean stress: ',triax.meanStress
  if unb<stabilityThreshold and abs(-5000-triax.meanStress)/5000<0.001:
    break
O.save('confinedState'+key+'.yade.gz')
print "### Isotropic state saved ###"

##############################
### DEVIATORIC LOADING ###
##############################

##We move to deviatoric loading, let us turn internal compaction off to keep particles sizes constant
triax.internalCompaction=False

## Change contact friction (remember that decreasing it would generate instantaneous instabilities)
setContactFriction(radians(finalFricDegree))

##set stress control on x and z, we will impose strain rate on y
triax.stressMask = 5 #mask = x*1 + y*2 + z*4, when x and z, 101
##now goal2 is the target strain rate
triax.goal2=rate
## we define the lateral stresses during the test, here the same 50kPa as for the initial confinement.
triax.goal1=-50000
triax.goal3=-50000

##we can change damping here.
newton.damping=0.7

##Save temporary state in live memory. This state will be reloaded from the interface with the "reload" button.
O.saveTmp()

#####################################################

### record and plot data ###

#####################################################

from yade import plot

### a function saving variables

def history():

   plot.addData(e11=-triax.strain[0], e22=-triax.strain[1], e33=-triax.strain[2],

        ev=-triax.strain[0]-triax.strain[1]-triax.strain[2],

      s11=-triax.stress(triax.wall_right_id)[0],

      s22=-triax.stress(triax.wall_top_id)[1],

      s33=-triax.stress(triax.wall_front_id)[2],

      sinPhi=(-triax.stress(triax.wall_right_id)[0]+triax.stress(triax.wall_front_id)[2])/(-triax.stress(triax.wall_right_id)[0]-triax.stress(triax.wall_front_id)[2]),

      #deviatoric=s11-s33,

      i=O.iter)

if 1:

  ## include a periodic engine calling that function in the simulation loop

  O.engines=O.engines[0:5]+[PyRunner(iterPeriod=20,command='history()',label='recorder')]+O.engines[5:7]

  ##O.engines.insert(4,PyRunner(iterPeriod=20,command='history()',label='recorder'))

else:

  ## With the line above, we are recording some variables twice. We could in fact replace the previous

  ## TriaxialRecorder

  ## by our periodic engine. Uncomment the following line:

  O.engines[4]=PyRunner(iterPeriod=20,command='history()',label='recorder')

O.run(100,True)

### declare what is to plot. "None" is for separating y and y2 axis

#plot.plots={'i':('e11','e22','e33',None,'s11','s22','s33')}

#plot.plots={'i':('s11','s22','s33'),'i':('e11','e22','e33')}
#plot.plots={'e22':('(s11-s33)/(s11+s33)',),}
plot.plots={'e22':('sinPhi',),}

### the traditional triaxial curves would be more like this:

##plot.plots={'e22':('s11','s22','s33',None,'ev')}

## display on the screen (doesn't work on VMware image it seems)

plot.plot()

##### PLAY THE SIMULATION HERE WITH "PLAY" BUTTON OR WITH THE COMMAND O.run(N) #####

## In that case we can still save the data to a text file at the the end of the simulation, with:

plot.saveDataTxt('results'+key)

##or even generate a script for gnuplot. Open another terminal and type "gnuplot plotScriptKEY.gnuplot:

plot.saveGnuplot('plotScript'+key)

The major problem is when the code finished the first loop, it will stop at the part of reaching target porosity. The following simulation cannot go through. However, i cannot find the reason. if anyone can point out the bug part, please reply me! Thank you so much and sorry for taking your time!

Regards,
Ting

Question information

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

Hello,
I have tried your code, but there is a syntax error:

compFricDegree = 0.85*compFricDegree
IndentationError: expected an indented block

please update your code such that we can try it. Also please try to make it minimal, meaning you delete everything which should be executed after your problem, since it is useless for the problem solution and makes the orientation difficult in such a long script (I guess it is why nobody reacted so far, nobody wants to find bugs in other's looong scripts).

cheers
Jan

Revision history for this message
Launchpad Janitor (janitor) said :
#2

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