Guest User

triaxial test HIEN

a guest
Apr 9th, 2013
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.31 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. from yade import pack
  3.  
  4. ############################################
  5. ###   DEFINING VARIABLES AND MATERIALS   ###
  6. ############################################
  7.  
  8. # Batch execution
  9. nRead=utils.readParamsFromTable(
  10.     num_spheres=10000,# number of spheres len(O.bodies) to verify: 10006 = 10000 particles + 6 walls is correct
  11.     compFricDegree = 24, # contact friction during the confining phase (1)
  12.     unknownOk=True,
  13.     isoForce=80000, # stress for the isotropic compression phase (1)
  14.     conStress=200000 # confinement stress, for the deviatoric loading session (2)
  15. )
  16. from yade.params import table
  17.  
  18. num_spheres=table.num_spheres           # number of spheres called from table
  19. targetPorosity = 0.382                  #the porosity we want for the packing (3 specimens: (Ei,n) = (1,0.382), (2,0.387), (3,0.409) )
  20. compFricDegree = table.compFricDegree   # initial contact friction during the confining phase (will be decreased during the REFD compaction process)
  21. finalFricDegree = 35                    # contact friction during the deviatoric loading
  22. rate=0.1                                # loading rate (strain rate)
  23. damp=0.06                               # damping coefficient
  24. stabilityThreshold=0.001                # initial value: 0.001
  25. key='_triax_draine_e618_200_24'             # simulation's name here
  26. young=356e6                             # contact stiffness k_n/Ds
  27. mn,mx=Vector3(-0.25,-0.25,-0.25),Vector3(0.25,0.25,0.25) # corners of the initial packing
  28. thick = 0.01                            # thickness of the plates
  29.  
  30.  
  31. ## create materials for spheres and plates
  32. O.materials.append(FrictMat(young=young,poisson=0.42,frictionAngle=radians(compFricDegree),density=3000,label='spheres'))
  33. O.materials.append(FrictMat(young=young,poisson=0.5,frictionAngle=0,density=0,label='walls'))
  34.  
  35. ## create walls around the packing
  36. walls=utils.aabbWalls([mn,mx],thickness=thick,oversizeFactor=1.5,material='walls')
  37. wallIds=O.bodies.append(walls)
  38.  
  39. ## use a SpherePack object to generate a random loose particles packing
  40. sp=pack.SpherePack()
  41. psdSizes=[0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.0095] # (sizes or radii of the grains vary from 2mm to 9.5mm)
  42. #psdCumm=[1,9,25,50,69,90,95,100] # the correspondent amount (percentage) of each diameter, uncomment for yade-stable
  43. psdCumm=[0.01,0.09,0.25,0.50,0.69,0.90,0.95,1.00] # for the code not using percentage, e.g. yade-daily
  44.  
  45. #---------------------------------------------
  46. #psdSizes=[0.002,0.004,0.008,0.0095] # (sizes or radii of the grains vary from 2mm to 9.5mm)
  47. #psdCumm=[1,25,95,100] # the correspondent amount (percentage) of each diameter
  48.  
  49. #clumps=False #turn this true for the same example with clumps
  50. #if clumps:
  51. # ## approximate mean rad of the futur dense packing for latter use
  52. # volume = (mx[0]-mn[0])*(mx[1]-mn[1])*(mx[2]-mn[2])
  53. # mean_rad = pow(0.09*volume/num_spheres,0.3333)
  54. # ## define a unique clump type (we could have many, see clumpCloud documentation)
  55. # c1=pack.SpherePack([((-0.2*mean_rad,0,0),0.5*mean_rad),((0.2*mean_rad,0,0),0.5*mean_rad)])
  56. # ## generate positions and input them in the simulation
  57. # sp.makeClumpCloud(mn,mx,[c1],periodic=False)
  58. # sp.toSimulation(material='spheres')
  59. #else:
  60.  
  61. ###################################################
  62. #method 01
  63. #sp.makeCloud(mn,mx,-1,0,num_spheres,False, 0.95,psdSizes,psdCumm,False,seed=1) #"seed" make the "random" generation always the same
  64. sp.makeCloud(mn,mx,0.00575,0.6,num_spheres,False,0.95,seed=1)
  65. #method 02
  66. #sp.particleSD(mn,mx,0.005635,True,'triaxial_test',5000,psdSizes,psdCumm,False,seed=0)
  67. #method 03
  68. #sp.particleSD2(psdSizes,psdCumm,10000,False,cloudPorosity=0.95,0)
  69.  
  70. # O.bodies.append([utils.sphere(center,rad,material='spheres') for center,rad in sp])
  71.  #or alternatively (higher level function doing exactly the same):
  72. sp.toSimulation(material='spheres')
  73.  
  74. ############################
  75. ###   DEFINING ENGINES   ###
  76. ############################
  77.  
  78. triax=TriaxialStressController(
  79.     maxMultiplier=1.001, # spheres growing factor (fast growth), validated only when internalCompaction = True
  80.     finalMaxMultiplier=1.00001, # spheres growing factor (slow growth), validated only when internalCompaction = True
  81.     thickness = thick,
  82.     ## switch stress/strain control using a bitmask. What is a bitmask, huh?!
  83.     ## Say x=1 if stress is controlled on x, else x=0. Same for for y and z, which are 1 or 0.
  84.     ## Then an integer uniquely defining the combination of all these tests is: mask = x*1 + y*2 + z*4
  85.     ## to put it differently, the mask is the integer whose binary representation is xyz, i.e.
  86.     ## "100" (1) means "x", "110" (3) means "x and y", "111" (7) means "x and y and z", etc.
  87.     stressMask = 7,
  88.     #the value of confining stress for the intitial (growth) phase
  89.     goal1=table.isoForce,
  90.     goal2=table.isoForce,
  91.     goal3=table.isoForce,
  92.     max_vel=0.5, # validated only when internalCompaction = False m/s
  93.     internalCompaction=True, # If true the confining pressure is generated by growing particles
  94. #   Key=key # passed to the engine so that the output file will have the correct name
  95. )
  96.  
  97. newton=NewtonIntegrator(damping=damp)
  98.  
  99. O.engines=[
  100.     ForceResetter(),
  101.     InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb()]),
  102.     InteractionLoop(
  103.         [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
  104.         [Ip2_FrictMat_FrictMat_FrictPhys()],
  105.         [Law2_ScGeom_FrictPhys_CundallStrack()]
  106.     ),
  107.     ## We will use the global stiffness of each body to determine an optimal timestep (see https://yade-dem.org/w/images/1/1b/Chareyre&Villard2005_licensed.pdf)
  108.     GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=25,timestepSafetyCoefficient=0.8),
  109.     triax,
  110.     TriaxialStateRecorder(iterPeriod=50,file='WallStresses'+key),
  111.     newton
  112. ]
  113.  
  114. O.save('initial'+key+'.xml')
  115. #Display spheres with 2 colors for seeing rotations better
  116. #Gl1_Sphere.stripes=0
  117. #if nRead==0: yade.qt.Controller(), yade.qt.View()
  118. print 'Number of elements: ', len(O.bodies)
  119. print 'Box Volume: ',  triax.boxVolume
  120. #######################################
  121. ###   APPLYING CONFINING PRESSURE   ###
  122. #######################################
  123.  
  124. while 1:
  125.   O.run(1000, True)
  126.   #the global unbalanced force on dynamic bodies, thus excluding boundaries, which are not at equilibrium
  127.   unb=unbalancedForce()
  128.   #average stress
  129.   #note: triax.stress(k) returns a stress vector, so we need to keep only the normal component
  130.   meanS=(triax.stress(triax.wall_right_id)[0]+triax.stress(triax.wall_top_id)[1]+triax.stress(triax.wall_front_id)[2])/3
  131.   print 'unbalanced force:',unb,' mean stress: ',meanS
  132.   print 'void ratio=',triax.porosity/(1-triax.porosity), 'porosity=', triax.porosity
  133.   print 'mean stress of engine', triax.meanStress
  134.   if unb<stabilityThreshold and abs(meanS-table.isoForce)/table.isoForce<0.001: #0.001
  135. #  if abs(triax.porosity-targetPorosity)<0.001:
  136.     break
  137.  
  138. O.save('confinedState'+key+'.xml')
  139. print "###      Isotropic state saved      ###"
  140. print 'current porosity=',triax.porosity
  141. print 'current void ratio=',triax.porosity/(1-triax.porosity)
  142.  
  143. ###################################################
  144. ###   REACHING A SPECIFIED POROSITY PRECISELY   ###
  145. ###################################################
  146.  
  147. ## We will reach a prescribed value of porosity with the REFD algorithm
  148. ## (see http://dx.doi.org/10.2516/ogst/2012032 and
  149. ## http://www.geosyntheticssociety.org/Resources/Archive/GI/src/V9I2/GI-V9-N2-Paper1.pdf)
  150.  
  151. # import sys #this is only for the flush() below
  152. # while triax.porosity>targetPorosity:
  153.     # # we decrease friction value and apply it to all the bodies and contacts
  154.     # compFricDegree = 0.95*compFricDegree
  155.     # setContactFriction(radians(compFricDegree))
  156.     # print "\r Friction: ",compFricDegree," porosity:",triax.porosity,
  157.     # sys.stdout.flush()
  158.     # # while we run steps, triax will tend to grow particles as the packing
  159.     # # keeps shrinking as a consequence of decreasing friction. Consequently
  160.     # # porosity will decrease
  161.     # O.run(500,1)
  162.  
  163. # O.save('compactedState'+key+'.xml')
  164. # print "###    Compacted state saved      ###"
  165. # print 'current porosity=',triax.porosity
  166. # print 'current void ratio=',triax.porosity/(1-triax.porosity)
  167. print 'step that starts the deviatoric loading ', O.iter
  168. ##############################
  169. ###   DEVIATORIC LOADING   ###
  170. ##############################
  171. #We move to deviatoric loading, let us turn internal compaction off to keep particles sizes constant
  172. triax.internalCompaction=False
  173.  
  174. # Change contact friction (remember that decreasing it would generate instantaneous instabilities)
  175. #setContactFriction(radians(finalFricDegree))
  176. setContactFriction(radians(35))
  177.  
  178. #set stress control on x and z, we will impose strain rate on y (5)
  179. triax.stressMask = 5
  180. #now goal2 is the target strain rate
  181. triax.goal2=-rate
  182. #we assign constant stress to the other directions
  183. triax.goal1=table.conStress
  184. triax.goal3=table.conStress
  185.  
  186. ##we can change damping here. What is the effect in your opinion?
  187. #newton.damping=0.1
  188.  
  189. ##Save temporary state in live memory. This state will be reloaded from the interface with the "reload" button.
  190. O.saveTmp()
  191.  
  192.  
  193. while triax.strain[1] < 0.25:
  194.   O.run(50); O.wait()
  195. ########################
  196. ## PLOT THE PSD CURVE ##
  197. ########################
  198.  
  199. #import matplotlib; matplotlib.rc('axes',grid=True)
  200. #from yade import pack
  201. #import pylab
  202. #pylab.plot(psdSizes,psdCumm,label='precribed mass PSD')
  203. #sp0=pack.SpherePack();
  204. #sp0.makeCloud(mn,mx,psdSizes=psdSizes,psdCumm=psdCumm,distributeMass=True)
  205. #sp1=pack.SpherePack();
  206. #sp1.makeCloud(mn,mx,psdSizes=psdSizes,psdCumm=psdCumm,distributeMass=True,num=10000)
  207. #sp2=pack.SpherePack();
  208. #sp2.makeCloud(mn,mx,psdSizes=psdSizes,psdCumm=psdCumm,distributeMass=True,num=20000)
  209. #pylab.semilogx(*sp0.psd(bins=30,mass=True),label='Mass PSD of (free) %d random spheres'%len(sp0))
  210. #pylab.semilogx(*sp1.psd(bins=30,mass=True),label='Mass PSD of (imposed) %d random spheres'%len(sp1))
  211. #pylab.semilogx(*sp2.psd(bins=30,mass=True),label='Mass PSD of (imposed) %d random spheres (scaled down)'%len(sp2))
  212.  
  213. #pylab.legend()
  214.  
  215. ## uniform distribution of size (sp3) and of mass (sp4)
  216. #sp3=pack.SpherePack(); sp3.makeCloud(mn,mx,rMean=0.005635,rRelFuzz=0,distributeMass=False);
  217. #sp4=pack.SpherePack(); sp4.makeCloud(mn,mx,rMean=0.005635,rRelFuzz=0,distributeMass=True);
  218. #pylab.figure()
  219. #pylab.plot(*(sp3.psd(mass=True)+('g',)+sp4.psd(mass=True)+('r',)))
  220. #pylab.legend(['Mass PSD of size-uniform distribution','Mass PSD of mass-uniform distribution'])
  221.  
  222. #pylab.figure()
  223. #pylab.plot(*(sp3.psd(mass=False)+('g',)+sp4.psd(mass=False)+('r',)))
  224. #pylab.legend(['Size PSD of size-uniform distribution','Size PSD of mass-uniform distribution'])
  225. #pylab.show()
  226.  
  227. #pylab.show()
  228.  
  229. #####################################################
  230. ###    Example of how to record and plot data     ###
  231. #####################################################
  232.  
  233.  
  234. from yade import plot
  235.  
  236. ## a function saving variables
  237. def history():
  238.     plot.addData(e11=triax.strain[0], e22=triax.strain[1], e33=triax.strain[2],
  239.             ev=-triax.strain[0]-triax.strain[1]-triax.strain[2],
  240.             s11=triax.stress(triax.wall_right_id)[0],
  241.             s22=triax.stress(triax.wall_top_id)[1],
  242.             s33=triax.stress(triax.wall_front_id)[2],
  243.             p=(triax.stress(triax.wall_right_id)[0]+triax.stress(triax.wall_top_id)[1]+triax.stress(triax.wall_front_id)[2])/3000,
  244.             q=(triax.stress(triax.wall_top_id)[1]-triax.stress(triax.wall_front_id)[2])/1000,
  245.             i=O.iter)
  246.  
  247. if 1:
  248.   # include a periodic engine calling that function in the simulation loop
  249.   O.engines=O.engines[0:5]+[PyRunner(iterPeriod=20,command='history()',label='recorder')]+O.engines[5:7]
  250.   O.engines.insert(4,PyRunner(iterPeriod=20,command='history()',label='recorder'))
  251. else:
  252.   # With the line above, we are recording some variables twice. We could in fact replace the previous
  253.   # TriaxialRecorder
  254.   # by our periodic engine. Uncomment the following line:
  255.   O.engines[4]=PyRunner(iterPeriod=20,command='history()',label='recorder')
  256.  
  257. O.run(100,True)
  258.  
  259. ### declare what is to plot. "None" is for separating y and y2 axis
  260. #plot.plots={'i':('e11','e22','e33',None,'s11','s22','s33')}
  261. ### the traditional triaxial curves would be more like this:
  262. plot.plots={'e22':('q')}
  263.  
  264. ## display on the screen (doesn't work on VMware image it seems)
  265. plot.plot()
  266.  
  267. #####  PLAY THE SIMULATION HERE WITH "PLAY" BUTTON OR WITH THE COMMAND O.run(N)  #####
  268.  
  269. ## In that case we can still save the data to a text file at the the end of the simulation, with:
  270. plot.saveDataTxt('results'+key)
  271. ##or even generate a script for gnuplot. Open another terminal and type  "gnuplot plotScriptKEY.gnuplot:
  272. plot.saveGnuplot('plotScript'+key)
Advertisement
Add Comment
Please, Sign In to add comment