linkos icon

Kinetic Energy Asking

linkos | PRO | 05/14/13 07:49:16 PM UTC | 0 ⭐ | 490 👁️ | Never ⏰ | []
Python |

7.04 KB

|

None

|

0 👍

/

0 👎

# -*- coding: utf-8 -*-
from yade import pack
 
############################################
###   DEFINING VARIABLES AND MATERIALS   ###
############################################
 
# Batch execution
nRead=utils.readParamsFromTable(
    num_spheres=10000,# number of spheres len(O.bodies) to verify: 10006 = 10000 particles + 6 walls is correct
    compFricDegree = 22, # contact friction
    unknownOk=True,
    isoForce=100000, # stress for the isotropic compression phase (1)
    conStress=100000 # confinement stress, for the deviatoric loading session
)
from yade.params import table
 
num_spheres=table.num_spheres
targetPorosity = 0.387 #the porosity we want for the packing (3 specimens: (Ei,n) = (1,0.382), (2,0.387), (3,0.409) )
compFricDegree = table.compFricDegree   # initial contact friction during the confining phase (will be decreased during the REFD compaction process)
finalFricDegree = 35 # contact friction during the deviatoric loading
rate=0.1 # loading rate (strain rate)
damp=0.06 # damping coefficient
stabilityThreshold=0.001 # initial value: 0.001
key='_triax_draine_e633_100kpa' # simulation's name here
young=356e6 # contact stiffness k_n/<Ds>
mn,mx=Vector3(-0.2,-0.2,-0.2),Vector3(0.2,0.2,0.2) # corners of the initial packing
thick = 0.01 # thickness of the plates
 
 
## create materials for spheres and plates
O.materials.append(FrictMat(young=young,poisson=0.42,frictionAngle=radians(compFricDegree),density=3000,label='spheres'))
O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
 
## create walls around the packing
walls=utils.aabbWalls([mn,mx],thickness=thick,oversizeFactor=1.5,material='walls')
wallIds=O.bodies.append(walls)
 
## use a SpherePack object to generate a random loose particles packing
sp=pack.SpherePack()
 
sp.makeCloud(mn,mx,0.005,0.7,num_spheres,False,0.8,seed=0) #"seed" make the "random" generation always the same
 
sp.toSimulation(material='spheres')
 
############################
###   DEFINING ENGINES   ###
############################
 
triax=TriaxialStressController(
    thickness = thick,
    stressMask = 7,
    radiusControlInterval=15, 
    goal1=table.isoForce,
    goal2=table.isoForce,
    goal3=table.isoForce,
    max_vel=2, # validated only when internalCompaction = False length/time
    internalCompaction=False, # 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=25,timestepSafetyCoefficient=0.8),
    triax,
    TriaxialStateRecorder(iterPeriod=100,file='WallStresses'+key),
    newton
]
 
O.save('initial'+key+'.xml')
#Display spheres with 2 colors for seeing rotations better
Gl1_Sphere.stripes=1
if nRead==0: yade.qt.Controller(), yade.qt.View()
print 'Number of elements: ', len(O.bodies)
#print 'Box Volume: ', triax.boxVolume
 
#######################################
###   APPLYING CONFINING PRESSURE   ###
#######################################
 
while 1:
  O.run(1000, True)
  #the global unbalanced force on dynamic bodies, thus excluding boundaries, which are not at equilibrium
  unb=unbalancedForce()
  #average stress
  #note: triax.stress(k) returns a stress vector, so we need to keep only the normal component
  meanS=(triax.stress(triax.wall_right_id)[0]+triax.stress(triax.wall_top_id)[1]+triax.stress(triax.wall_front_id)[2])/3
  print 'unbalanced force:',unb,' mean stress: ',meanS
  print 'void ratio=',triax.porosity/(1-triax.porosity), 'porosity=', triax.porosity
  print 'mean stress of engine', triax.meanStress
  if unb<stabilityThreshold and abs(meanS-table.isoForce)/table.isoForce<0.001: #0.001
    break
 
O.save('confinedState'+key+'.xml')
print "###  Isotropic state saved  ###"
print 'current porosity=',triax.porosity
print 'current void ratio=',triax.porosity/(1-triax.porosity)
 
 
print 'step that starts the deviatoric loading ', O.iter
 
from yade import plot
from pprint import pprint
plot.reset()
e22Check=triax.strain[1]
plot.addData(CheckpointStep=O.iter,Porosity=triax.porosity,e22=triax.strain[1])
plot.saveDataTxt('checkpoint.txt',vars=('CheckpointStep','Porosity','e22'))
 
##############################
###   DEVIATORIC LOADING   ###
##############################
 
# Change contact friction (remember that decreasing it would generate instantaneous instabilities)
#setContactFriction(radians(finalFricDegree))
setContactFriction(radians(35))
 
#set stress control on x and z, we will impose strain rate on y (5)
triax.stressMask = 5
#now goal2 is the target strain rate
triax.goal2=-rate
#we assign constant stress to the other directions
triax.goal1=table.conStress
triax.goal3=table.conStress
 
##we can change damping here. What is the effect in your opinion?
#newton.damping=0.1
 
##Save temporary state in live memory. This state will be reloaded from the interface with the "reload" button.
O.saveTmp()
 
 
while (triax.strain[1]-e22Check) < 0.30: # stop condition: the simulation will stop at epsilon = 0.3
  O.run(50); O.wait()
 
#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],
#           p=(triax.stress(triax.wall_right_id)[0]+triax.stress(triax.wall_top_id)[1]+triax.stress(triax.wall_front_id)[2])/3000,
#           q=(triax.stress(triax.wall_top_id)[1]-triax.stress(triax.wall_front_id)[2])/1000,
#           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')}
#### the traditional triaxial curves would be more like this:
#plot.plots={'e22':('q')}
 
### 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)

Comments