New question #700164 on Yade: https://answers.launchpad.net/yade/+question/700164
Hi There, I'm trying to model a soil-wheel interaction using MPI. Originally, my DEM model consisted of a larger of highly irregular-shaped clump particles but since YADE MPI has not been designed for clumps, I decided to run the same problem with spherical particles from those clumps. I have set up the model and it started working but no collision occurs between my external moving object which is a facet wheel and the underlying spheres. This is a two-phase problem where the wheel first penetrates into the soil and then starts rotating in the longitudinal direction where the position of the zero point is continually updated. Here is my code missing the DEM geometry (which is imported). As most MPI exampmples in YADE deal with gravity deposition only, I'm wondering if it is possible to model soil-tool interactions like the one I have here. 1- Am I missing something regarding collision establishment? 2- Do I need any adjustments for the rank of my facet wheel to enable collision and getting forces on the wheel? Thanks so much from yade import pack, export from yade import pack, plot from yade import ymport import sys import os import os.path import numpy import math import os from yade import mpy as mp from yade import timing NSTEPS=100 #turn it >0 to see time iterations, else only initilization numThreads = 9 # number of threads to be spawned, (in interactive mode). ############################################ ### INPUT PARAMETERS ### ############################################ ## Wheel PROPERTIES rmean=5.56539971721455E-05 widthWheel=0.00125 Wheel_R=0.0025 Wheel_AdditionalNormalForce=-19.6 ##WHELL MOVEMENT slidingratio=0.3 velocity=0.1 #m/s THAT SHOULD BE 0.01 m/s angularVelocity=velocity/((1-slidingratio)*Wheel_R) #RAD/S gravityAcc=-9.81 deposFricDegree = 28.5 # INITIAL CONTACT FRICTION FOR SAMPLE PREPARATION normalDamp=0.7 # NUMERICAL DAMPING shearDamp=0.7 youngSoil=0.7e8# CONTACT STIFFNESS FOR SOIL youngContainer=210e9 # CONTACT STIFFNESS FOR CONTAINER poissonSoil=0.3 # POISSION'S RATIO FOR SOIL poissionContainer=0.25 # POISSION'S RATIO FOR CONTAINER densSoil=2650 # DENSITY FOR SOIL densContainer=7850 # DENSITY FOR CONTAINER numDamp=0.4 binSize=0.4*Wheel_R activeDistance=0.01 iniDistanceWheelfromBoundary=0.004 differenceWCenterActiveEnd=activeDistance - iniDistanceWheelfromBoundary initialPeneterationofWheel=0.001 iniWheelDisfromMaxY=0.0001 ############################################ ### DDEFINING VARIABLES AND MATERIALS ### ############################################ SoilId=FrictMat(young=youngSoil,poisson=poissonSoil,frictionAngle=radians(deposFricDegree),density=densSoil) O.materials.append(SoilId) ContainerId=FrictMat(young=youngContainer,poisson=poissionContainer,frictionAngle=radians(0),density=densContainer) O.materials.append(ContainerId) ################################### ##### CREATING GEOMETRIES ##### ################################### ## IMPORTING THE ALREADY COMPACTED BIN O.bodies.append(ymport.text("/home/ngoudarzi/Desktop/SWI MPI/Half Width/5by6by20_n057_Relaxed_FreeSurface_Spheres.txt",shift=Vector3(0,0,0),material=SoilId)) minX=min([b.state.pos[0]-b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) maxX=max([b.state.pos[0]+b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) minY=min([b.state.pos[1]-b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) maxY=max([b.state.pos[1]+b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) minZ=min([b.state.pos[2]-b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) maxZ=max([b.state.pos[2]+b.shape.radius for b in O.bodies if isinstance(b.shape,Sphere)]) print ("minX:",minX,"maxX:",maxX,"minY:",minY,"maxY:",maxY,"minZ:",minZ,"maxZ:",maxZ) mn,mx=Vector3(minX,minY,minZ),Vector3(maxX,0.01,maxZ) ## CREATE WALLS AROUND THE PACKING walls=aabbWalls([mn,mx],thickness=0,material=ContainerId) wallIds=O.bodies.append(walls) for b in O.bodies: if b.state.pos[1]>0.009: O.bodies.erase(b.id) widthWheel=maxX-minX XcenterofWheel = widthWheel/2+minX YcenterofWheel = Wheel_R+maxY+iniWheelDisfromMaxY ZcenterofWheel = iniDistanceWheelfromBoundary+minZ Wheel1 = geom.facetCylinder((XcenterofWheel,YcenterofWheel,ZcenterofWheel),radius=Wheel_R,height=widthWheel,orientation=Quaternion((0,1,0),-pi/2),wallMask=7,segmentsNumber=1000,material=ContainerId,wire=True,color=Vector3(255,255,255)) O.bodies.append(Wheel1) idsr = [w.id for w in Wheel1] facets = [b for b in O.bodies if isinstance(b.shape,Facet)] # list of facets in simulation for b in facets: O.forces.setPermF(b.id,(0,Wheel_AdditionalNormalForce/800,0)) ############################ ### DEFiniNG ENGINES ### ############################ O.engines=[ ForceResetter(), InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb(),Bo1_Facet_Aabb()], label="collider"), InteractionLoop( [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()], [Ip2_FrictMat_FrictMat_MindlinPhys(betan=normalDamp,betas=shearDamp,label='ContactModel')], [Law2_ScGeom_MindlinPhys_Mindlin(label='Mindlin')] ), ## 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) #GlobalStiffnessTimeStepper(active=1,timeStepUpdateInterval=100,timestepSafetyCoefficient=0.25,parallelMode=True, label = 'timeStepper'), CombinedKinematicEngine(ids=idsr,label='combEngine') + TranslationEngine(translationAxis=(0,-1,0),velocity=velocity) +\ RotationEngine(rotationAxis=(1,0,0), angularVelocity=0, rotateAroundZero=True, zeroPoint=(XcenterofWheel,YcenterofWheel,ZcenterofWheel)), NewtonIntegrator(damping=numDamp,gravity=(0,gravityAcc,0)), VTKRecorder(fileName='/home/ngoudarzi/Desktop/SWI MPI/Half Width/VTKWheel/Output', recorders=['all'], parallelMode=True,iterPeriod=500), #use .pvtu to open spheres, .pvtp for ints, and .vtu for boxes. PyRunner(iterPeriod=1, command="WheelPenetration()" ,label='checker'), PyRunner(iterPeriod=100,command='history()',label='recorder'), PyRunner(iterPeriod=1000,command='eraseOffs()'), ] O.dt = 1e-7 collider.verletDist = 0.05*rmean # get TranslationEngine and RotationEngine from CombinedKinematicEngine transEngine, rotEngine = combEngine.comb[0], combEngine.comb[1] def WheelPenetration(): transEngine.velocity = 7*velocity rotEngine.zeroPoint += Vector3(0,-1,0)*transEngine.velocity*O.dt timing.reset() t=time.time() print("rotEngine.zeroPoint[1]-Wheel_R: ",(rotEngine.zeroPoint[1]-Wheel_R),"Iteration",O.iter,"Ellapsed Time",O.time) if (rotEngine.zeroPoint[1]-Wheel_R)<=(maxY-initialPeneterationofWheel): print("PENETRATION PERFORMED, ROLLING IS BEING STARTED") checker.command='WheelRolling()' def WheelRolling(): transEngine.translationAxis=(0,0,1) transEngine.velocity = velocity rotEngine.angularVelocity = angularVelocity rotEngine.zeroPoint += Vector3(0,0,1)*velocity*O.dt print("rotEngine.zeroPoint[2]: ",rotEngine.zeroPoint[2],"Iteration",O.iter,"Ellapsed Time",O.time) if rotEngine.zeroPoint[2]>=maxZ-1.05*Wheel_R: print("ROLLING PERFORMED") O.pause() def history(): global Fx,Fy,Fz,Dx,Dy,Dz Fx=0 Fy=0 Fz=0 for b in facets: Fx+=O.forces.f(b.id,sync=True)[0] Fy+=O.forces.f(b.id,sync=True)[1] Fz+=O.forces.f(b.id,sync=True)[2] Dx=rotEngine.zeroPoint[0] Dy=rotEngine.zeroPoint[1] Dz=rotEngine.zeroPoint[2] yade.plot.addData({'i':O.iter,'Fx':Fx,'Fy':Fy,'Fz':Fz,'Dx':Dx,'Dy':Dy,'Dz':Dz,}) ## In that case we can still save the data to a text file at the the end of the simulation, with: plot.saveDataTxt('/home/ngoudarzi/Desktop/SWI MPI/Half Width/Wheel_OutputData_5by6by20_n057_Relaxed_FreeSurface.txt') ## declare what is to plot. "None" is for separating y and y2 axis plot.plots={'i':('Fx','Fy','Fz','Dx','Dy','Dz')} plot.plot() ######### RUN ########## # customize mpy mp.ERASE_REMOTE_MASTER = True #keep remote bodies in master? mp.DOMAIN_DECOMPOSITION= True #automatic splitting/domain decomposition #mp.mpirun(NSTEPS) #passive mode run mp.MERGE_W_INTERACTIONS = False mp.mpirun(NSTEPS,numThreads,withMerge=True) # interactive run, numThreads is the number of workers to be initialized, see below for withMerge explanation. mp.mergeScene() #merge scene after run. if mp.rank == 0: O.save('/home/ngoudarzi/Desktop/SWI MPI/Half Width/mergedScene.yade') #demonstrate getting stuff from workers, here we get kinetic energy from worker subdomains,notice that the master (mp.rank = 0), uses the sendCommand to tell workers to compute kineticEnergy. if mp.rank==0: print("kinetic energy from workers: "+str(mp.sendCommand([1,2],"kineticEnergy()",True))) -- 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 : yade-users@lists.launchpad.net Unsubscribe : https://launchpad.net/~yade-users More help : https://help.launchpad.net/ListHelp