0 引言
最近在熟悉PFC6.0的内容,对于6.0来说,其最大的突破就是实现了软件内与FLAC3D的耦合。这其实解决了PFC很大的一个问题,就是颗粒数太多时计算力的限制,我们可以用网格单元作为边界来弱化边界效应,当然也可以和本文一样,使用网格单元模拟金属等连续性材料。
本文试着去模拟一个结构方向同学经常遇到的一个工况,霍普金森压杆(SHPB)实验,对于测量混凝土材料在高应变率下的力学特性有很大的参考价值。因为我这里也没有看过这方面的实验,仅从有限的资料大概理解其边界设置,利用有限差分和离散元耦合来实现SHPB压杆模拟,希望能给各位有一定的参考价值。
1 成样、预压、加胶结
首先是我们的离散元部分,这里进行常规的方式来生成一个圆柱形式样。这里不再赘述了。
成样代码:
model newfish define Parsample_width=0.05radmin=0.8e-3radmax=radmin*1.8poro=0.28sample_rad=sample_width*0.5poleLength=sample_width*40end@Parmodel domain extent [-sample_width] [sample_width]wall generate cylinder base [-sample_width*0.5*1.4] 0 0 axis 1 0 0 ...height [sample_width*1.4] radius [sample_rad] resolution 0.3 cap false falsewall generate plane position [sample_width*0.5] 0 0 dip 90 dip-dir 90wall generate plane position [-sample_width*0.5] 0 0 dip 90 dip-dir 90ball distribute group "shiyang" radius [radmin] [radmax] porosity @poro ...range cylinder end-1 [sample_width*0.5-radmax] 0 0 ...end-2 [-sample_width*0.5 radmax] 0 0 radius [sample_rad-radmax]cmat default type ball-facet model linear method deform emod 100e6 kratio 1.5cmat default type ball-ball model linear method deform emod 100e6 kratio 1.5ball attribute density 2.7e3 damp 0.2model cycle 2000 calm 50model solvemodel save "sample"
预压代码:
model restore "sample"ball property "fric" 0.5fish def wp_wallwp_up=wall.find(2)wp_down=wall.find(3)wp_rr=wall.find(1)loop foreach vt wall.vertexlist(wp_rr)vert_in_ce=vtendloopend@wp_wall[txx=-1e6][trr=-1e6][sevro_fac=0.5][do_xservo=true][do_rservo=true][sevro_freq=100][timestepNow=global.step-1]fish def servo_wallscomputer_wallStressif timestepNow<global.step thenget_gain(sevro_fac)timestepNow =sevro_freqendifif do_xservo=true thenx_vel=gx*(wsxx-txx)wall.vel.x(wp_up)=-x_velwall.vel.x(wp_down)=x_velendifif do_rservo=true thenr_vel_mag=(-1)*gr*(wsrr-trr)loop foreach vt wall.vertexlist(wp_rr)mag=math.sqrt(wall.vertex.pos.y(vt)^2 wall.vertex.pos.z(vt)^2)fang_normal_y=wall.vertex.pos.y(vt)/magfang_normal_z=wall.vertex.pos.z(vt)/magr_vel=vector(0,fang_normal_y,fang_normal_z)*r_vel_magwall.vertex.vel(vt)=r_velendloopendifendfish def computer_chicuny_pos=wall.vertex.pos.y(vert_in_ce)z_pos=wall.vertex.pos.z(vert_in_ce)wlr=math.sqrt(y_pos^2 z_pos^2)wlx=wall.pos.x(wp_up)-wall.pos.x(wp_down)endfish def computer_wallStresscomputer_chicunding_yuanmianji=math.pi*wlr^2wsxx=(wall.force.contact.x(wp_down)-wall.force.contact.x(wp_up))*0.5/ding_yuanmianjice_mianji=2*math.pi*wlr*wlxwsrr=0loop foreach ft wall.facetlist(wp_rr)ft_fangxiang=wall.facet.normal(ft)loop foreach ct wall.facet.contactmap(ft)force_in_facet=contact.force.global(ct)wsrr =(math.dot(force_in_facet,ft_fangxiang))/ce_mianjiendloopendloopenddef get_gain(fac)gx=0gr=0zonggangX=1e7zonggangR=1e7loop foreach ct wall.contactmap(wp_up)zonggangX =contact.prop(ct,"kn")endlooploop foreach ct wall.contactmap(wp_down)zonggangX =contact.prop(ct,"kn")endlooploop foreach ct wall.contactmap(wp_rr)zonggangR =contact.prop(ct,"kn")endloopgX=fac*ding_yuanmianji/(zonggangX*global.timestep)gr=fac*ce_mianji/(zonggangR*global.timestep)endfish callback add @servo_walls -1.0history id 1 @wsXXhistory id 2 @wsrrmodel cycle 1model solvemodel save "yuya"
加胶结代码
model restore "yuya"[pb_coh=100e6][ten_coh=2.7]contact cmat default type ball-facet model linear method deformability emod 10e8 kratio 1.5contact cmat default type ball-ball model linearpbond method deformability ...emod 12e8 kratio 1.5 pb_deformability emod 54e8 kratio 1.5 ...property "pb_coh" [pb_coh] "pb_ten" [pb_coh*ten_coh] "pb_fa" 50 "fric" 0contact cmat applymodel cycle 1model solvecontact method bond gap [radmin*0.5]model cycle 1model solvemodel save "jiajiaojie"
生成的式样如图

2、卸载
这里模拟混凝土从模具中取出,或者岩石从地下取出的过程,所以预压的值是有讲究的。
model restore "jiajiaojie"[txx=-1e3][trr=-1e3]model cycle 1model solvemodel save "xiezai"
3、生成压杆
这部分需要生产入射杆和透射杆的单元,目前我知道的方式是通过四个1/4的cylinder拼起来,不知道会不会有更便捷的方法,可以后台交流。
之后就是耦合部分的定义,PFC和FLAC提供了两种耦合方式,wall-zone耦合与ball-zone耦合,就使用来看,本文应当用wall-zone耦合来实现zone与ball之间的力学联系。
需要注意的一点是,由于我们的杆件是拼起来的,所以zone生成wall时,会出现重复点的情况,这里可以直接指定skip-errors跳过即可。
model restore "xiezai"model domain extent [-poleLength*1.5] [poleLength*1.5] ...[-sample_width] [sample_width]wall deletefish callback remove @servo_walls -1.0[materialMod=200e9]model largestrain on[bullet_Length=sample_width*8][midu=5]zone create cylinder point 0 ([-poleLength-wlx*0.5],0,0) ...point 1 ([-poleLength-wlx*0.5],[-sample_rad],0) ...point 2 ([-wlx*0.5],0,0) ...point 3 ([-poleLength-wlx*0.5],0,[sample_rad]) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ImportPole"zone create cylinder point 0 ([-poleLength-wlx*0.5],0,0) ...point 1 ([-poleLength-wlx*0.5],0,[-sample_rad]) ...point 2 ([-wlx*0.5],0,0) ...point 3 ([-poleLength-wlx*0.5],[-sample_rad],0) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ImportPole"zone create cylinder point 0 ([-poleLength-wlx*0.5],0,0) ...point 1 ([-poleLength-wlx*0.5],[sample_rad],0) ...point 2 ([-wlx*0.5],0,0) ...point 3 ([-poleLength-wlx*0.5],0,[-sample_rad]) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ImportPole"zone create cylinder point 0 ([-poleLength-wlx*0.5],0,0) ...point 1 ([-poleLength-wlx*0.5],0,[sample_rad]) ...point 2 ([-wlx*0.5],0,0) ...point 3 ([-poleLength-wlx*0.5],[sample_rad],0) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ImportPole"; toushezone create cylinder point 0 ([wlx*0.5],0,0) ...point 1 ([wlx*0.5],[-sample_rad],0) ...point 2 ([poleLength wlx*0.5],0,0) ...point 3 ([wlx*0.5],0,[sample_rad]) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ExportPole"zone create cylinder point 0 ([wlx*0.5],0,0) ...point 1 ([wlx*0.5],0,[-sample_rad]) ...point 2 ([poleLength wlx*0.5],0,0) ...point 3 ([wlx*0.5],[-sample_rad],0) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ExportPole"zone create cylinder point 0 ([wlx*0.5],0,0) ...point 1 ([wlx*0.5],[sample_rad],0) ...point 2 ([poleLength wlx*0.5],0,0) ...point 3 ([wlx*0.5],0,[-sample_rad]) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ExportPole"zone create cylinder point 0 ([wlx*0.5],0,0) ...point 1 ([wlx*0.5],0,[sample_rad]) ...point 2 ([poleLength wlx*0.5],0,0) ...point 3 ([wlx*0.5],[sample_rad],0) ...size @midu [math.floor(midu*poleLength/sample_rad)] @midu group "ExportPole"zone cmodel assign elasticzone property young [materialMod] poisson 0.25wall-zone create skip-errors range position-x [-wlx*0.5-0.001] [-wlx*0.5 0.001]wall-zone create skip-errors range position-x [wlx*0.5-0.001] [wlx*0.5 0.001]model save "pole"
生产的压杆如图:

细节放大:
可以发现此时颗粒是有一定速度的,但是由于我们研究的是高应变率所以这里可以不用管。

4、加载
这里直接施加一个冲击荷载,在入射杆的端部指定一个200MPa的应力,持续200us。之后接触边界条件,运算1500us。
model restore "pole"model mechanical time-total 0model configure dynamicball attribute displacement multiply 0zone face group "rushe" range position-x [-poleLength-wlx*0.5-0.001] ...[-poleLength-wlx*0.5 0.001]zone face apply stress-xx [(-1)*(200e6)] range group "rushe"zone initialize density 7.8e3model cycle 1measure create position 0 0 0 radius [wlr*0.5]def cedianzoneImportPole=zone.near(vector(-wlx*0.5-poleLength*0.5,[-wlr],0))zoneExportPole=zone.near(vector(wlx*0.5 poleLength*0.5,[-wlr],0))mp1=measure.find(1)zone.group(zoneImportPole,"cedianGroup")="cedian"zone.group(zoneExportPole,"cedianGroup")="cedian"stressShiyang0=measure.stress.xx(mp1)end@cediandef jiancetime=mech.time.totalstressImport=zone.stress.xx(zoneImportPole)stressExport=zone.stress.xx(zoneExportPole)stressShiyang=measure.stress.xx(mp1)-stressShiyang0endfish callback add @jiance -1.0history deletehistory id 1 @stressImporthistory id 2 @stressExporthistory id 3 @stressShiyanghistory id 4 @time[baocunpinlv=500e-6][time_record=-10][count=0]def savefileif time-time_record >= baocunpinlv thenfilename=string.build("jieguo%1",count)commandmodel save @filenameendcommandtime_record=timecount =1endifendfish callback add @savefile -1.0program call "fracture.p3fis"@track_initmodel solve time 200e-6zone face apply-remove stress-xx range group "rushe"model solve time 1500e-6model save "jieguo"
5、结果分析
首先本文选用的微观参数强度比较大,不会发生破坏,这也是为了和有限元的一些结果做对比。
先看一下应力波形图
这里给出参考曲线:

本文的模拟结果为:

可以看出无论是波形还是数值,都是在一个比较正常的范围内的。所以也是论证了我们程序的正确性。
压杆上的应力传递到式样时候的图片:

力链图:

后续各位可以根据自己的实际材料结果进行更多的研究。