首页/文章/ 详情

简述PFC成样方法

2月前浏览6764

本文摘要(由AI生成):

本文介绍了两种生成均匀试样的方法:分层压缩法和Brick方法。分层压缩法通过循环和状态调整来优化单次distribute的结果,提高了试样的均匀性。而Brick方法则通过先生成小块再组装的方式,显著提升了计算速度,尤其适用于大数量颗粒的试样。实验结果表明,对于颗粒数量较少的试样,分层压缩法效果较佳;而对于颗粒数量众多的试样,Brick方法则是首选。


这部分内容包括:


    粒径放大 法、压缩法、分层压缩、distribute成样法、分层成样法、Brick方法


    PFC生成颗粒的方法其实经历过了很长时间的发展,这里从发展的逻辑顺序来讲一下PFC中的成样方法。虽然是简述,但是这部分内容比较多,包含了我阅读的文献内容和自己经验和理解,建议或许可以打印下来学习理解一下。


    密样因为接触力的调整,最后肯定会比较均匀,所以松样才是衡量成样好坏的标准。


    我们这里生成的试样为:


    长宽为1.5m,两个粒径的颗粒,一个是0.006半径的,一个是0.009半径的,两个体积百分比一样,孔隙率为0.25。



一、generate方法


    generate方法为在指定区域生成指定数量的无重叠的颗粒(这句话理解一下)。可以看做是往一个棋盘上摆棋子这种感觉,颗粒是一个个生成的。逻辑方法为:1)生成随机数,确定区域内的坐标;2)判断坐标位置生成颗粒的话,会不会和别的颗粒重叠,如果重叠,回到第一步。


    这里就会暴露出generate方法的一个问题,就是可能在指定的循环次数内,找不到符合条件的坐标了,这样在区域内生成的颗粒就会远远少于指定的数目,下面用个demo说明一下这个问题。


    根据试样的条件,我们可以计算出两个粒径的颗粒数。逻辑为:试样颗粒体积 Vs=(1-poro)*V ,其中poro为孔隙率,V为试样体积。如果两个颗粒的质量百分比一样的话(如果密度一样,体积百分比也一样),两个粒径的颗粒体积为 Vs1=Vs2=Vs*0.5 。一个颗粒的体积为 pi*r*r ,这样颗粒数为 Vs1/(pi*r*r)。于是乎命令流为:






























new def par    width=1.5    height= width      rdmax=0.009    rdmin=0.006        poro=0.25
   rdmax_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmax*rdmax))    rdmin_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmin*rdmin))end@pardomain extent [-height*5] [height*5]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5ball generate radius @rdmin number @rdmin_num box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]ball generate radius @rdmax number @rdmax_num box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]cmat default model linear method deformability emod 10e9 kratio 1.5 ball attribute density 2.7e3 damp 0.7cycle 2000 calm 50solve save sample_generate_1_1


    

最后会出现warning:


image.png



    可以看出第一个粒径会生成7004个颗粒,但是指定数目为7460,少了一点。但是当第一种颗粒占了很大区域之后,第二种颗粒目标数目为3315,却只生成了96个。如图


微信截图_20220718153117.png



    针对这个问题,出现了两种解决办法——粒径膨胀法和压缩法。原理很简单,既然指定区域生成不了指定数目的颗粒,那我就减小颗粒粒径,或者增大区域。


(1) 减小颗粒粒径的方法——粒径膨胀法


    这个思路就是先将粒径减小,生成指定数目后,再将粒径增大。这里给出demo,这里定义了膨胀系数为5.0,就是先将粒径减小五倍,之后再放大。


































new def par    width=1.5    height= width      rdmax=0.009    rdmin=0.006        poro=0.25
   rdmax_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmax*rdmax))    rdmin_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmin*rdmin))
   pengzhangxishu=5.0end@pardomain extent [-height*5] [height*5]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5ball generate radius [rdmin/pengzhangxishu] number @rdmin_num box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]ball generate radius [rdmax/pengzhangxishu] number @rdmax_num box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]cmat default model linear method deformability emod 10e9 kratio 1.5ball attribute density 2.7e3 damp 0.7cycle 2000 calm 50cycle 4000save init_generate_pengzhangball attribute radius multiply @pengzhangxishucycle 2000 calm 50solvesave sample_generate_1_2


从console里面可以看到指定数目的颗粒生成了

image.png

模型图可以看出来颗粒非常小

image.png



之后放大粒径后的状态为:



image.png

一共10775个颗粒全部生成。


以上为粒径膨胀法的概念


(2) 增加区域面积的方法——压缩法


      压缩法的概念是,保持粒径不变,我先将区域放大,然后移动墙体,使其移动到指定的区域面积。以下为这个逻辑的demo,区域放大系数为5.0,也就是先将区域放大五倍,然后移动上部墙体,移动4.0倍的区域距离。


















































new def par    width=1.5    height= width      rdmax=0.009    rdmin=0.006        poro=0.25
   rdmax_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmax*rdmax))    rdmin_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmin*rdmin))
   pengzhangxishu=5.0
   y_vel=100.0end@pardomain extent [-height*pengzhangxishu*2] [height*pengzhangxishu*2]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*(pengzhangxishu-1) height*0.5] expand 1.5
ball generate radius [rdmin] number @rdmin_num box [-width*0.5] [width*0.5] ...                                            [-height*0.5] [height*(pengzhangxishu-1) height*0.5]ball generate radius [rdmax] number @rdmax_num box [-width*0.5] [width*0.5] ...                                             [-height*0.5] [height*(pengzhangxishu-1) height*0.5]cmat default model linear method deformability emod 10e9 kratio 1.5
ball attribute density 2.7e3 damp 0.7
cycle 2000 calm 50
cycle 4000
save init_generate_quyu
wall attribute yvel [-y_vel] range id 3
solve time [height*(pengzhangxishu-1)/y_vel]
wall attribute yvel 0 range id 3
solvesave sample_generate_1_3


    这里先给出扩大区域内试样的状态,这里的粒径还是指定的,只是因为区域比较大,所以视觉上看颗粒显得小点。


image.png压缩后的状态如图:

image.png


    可以看出来,虽然生成了指定数目的颗粒了,但是试样在上方比较密,在下方比较松,这样必然会导致试样的不均匀性,于是很多学者对其进行了拓展,基本的拓展方法为分层压缩法。



(3) 压缩法的拓展——分层压缩法


    分层压缩法的基本思路为,将压缩法分为几次(5-10次)进行压缩,这样前述的压缩法的缺点就会被忽略掉。下方给出分层压缩法的demo:


    这里用loop循环执行分层操作,每次先删除之前的顶部墙,生成新的顶部墙,然后按照压缩法进行成样,重复层数就是我们的分层压缩法。


















































new def par    width=1.5    height= width       rdmax=0.009    rdmin=0.006        poro=0.25         rdmax_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmax*rdmax))    rdmin_num=math.floor((1-poro)*0.5*width*height/(math.pi*rdmin*rdmin))        pengzhangxishu=5.0        y_vel=100.0        cengshu=8.0end@pardomain extent [-height*pengzhangxishu*2] [height*pengzhangxishu*2]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*(pengzhangxishu-1)-height*0.5] expand 1.5cmat default model linear method deformability emod 10e9 kratio 1.5 
def create_sample    loop n(1,cengshu)        dibuzuobiao=-width*0.5 height*(n-1)/cengshu        dingbuzuobiao=-width*0.5 height*(n)/cengshu                pengzhangGaoDu=dingbuzuobiao height*(pengzhangxishu-1)/cengshu    
       group_string=string.build("keli_%1",n)        jieguo_string=string.build("bushu_%1",n)        command            wall delete walls range id 3            wall create id 3 vertices [-width*0.5*1.5] [pengzhangGaoDu] [width*0.5*1.5] [pengzhangGaoDu]            ball generate radius [rdmin] number [math.floor(rdmin_num/cengshu)] box [-width*0.5] [width*0.5] ...                                            [dibuzuobiao] [pengzhangGaoDu] group @group_string            ball generate radius [rdmax] number [math.floor(rdmax_num/cengshu)] box [-width*0.5] [width*0.5] ...                                            [dibuzuobiao] [pengzhangGaoDu] group @group_string            ball attribute density 2.7e3 damp 0.7            wall attribute yvel [-y_vel] range id 3            solve time [(pengzhangGaoDu-dingbuzuobiao)/y_vel]                        wall attribute yvel 0 range id 3            cycle 2000
           save @jieguo_string        endcommand            endloopend@create_samplesolvesave sample_generate_1_4


这里分8次成样,下面给出执行中的试样状态:


第一次压缩:



image.png

第四次压缩:


image.png


第八次压缩:


image.png


最后状态的试样为:

image.png



这里可以看出压缩法的缺陷已经得到明显的改善。


增加压缩次数试样会更加均匀,下面为分16次压缩:


image.png

image.png



    很多学者对于压缩时候的能量传递进行研究,认为由于压缩能的影响,下部的颗粒在成样的时候应该松一点,上部的颗粒应该密一点。这时候我们可以改变孔隙率实现这个想法,具体为:如分5层,则5层的孔隙率为 1.08*poro,1.04*poro,poro,0.96*poro,0.92*poro。这个可以根据试样的情况去调。也有一些学者对孔隙率的值进行了定值研究,国内比较著名的就是分层欠压法(蒋),这部分同学们可以参考文献自己去定义,虽然我懂这个东西,但是不知道能不能讲,防止被告,还是不讲了。



、distribute方法


(1) 基本的distribute法


    这个方法应该是generate方法后面出来的,为了克服generate方法的缺点,distribute允许颗粒有很大的重叠,这样在指定的区域内必然可以生成指定数目的颗粒。这个逻辑为:根据区域面积和孔隙率计算颗粒体积,然后根据颗粒体积计算颗粒数目,在指定区域内堆叠生成颗粒。


    为了克服大重叠引起的颗粒很大的初速度,我们需要先利用calm命令清除颗粒的动能。这里给出distribute命令的demo,这里需要计算两个粒径颗粒的孔隙率。逻辑为:Vs=(1-poro)*V*0.5,则Vsporo=(V-(1-poro)*V*0.5)/V=1-(1-poro)*0.5。


    cycle 2000 calm 50 就是为了清除颗粒的初速度,如果还是有颗粒飞出来的话,就需要使用calm 10 或者calm 5。




























new def par    width=1.5    height= width      rdmax=0.009    rdmin=0.006        poro=0.25
   vsporo=1-(1-poro)*0.5end@pardomain extent [-height*5] [height*5]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5ball distribute porosity  @vsporo radius @rdmin box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]ball distribute porosity @vsporo radius @rdmax box [-width*0.5] [width*0.5] ...                                                        [-height*0.5] [height*0.5]cmat default model linear method deformability emod 10e9 kratio 1.5ball attribute density 2.7e3 damp 0.7cycle 2000 calm 50solve save sample_distribute_2_1


刚生成颗粒时候的状态如下,可以看出很大的重叠量



image.png


进行平衡后的试样如图:

image.png


(2) 分层成样法


    这里也是用distribute命令进行成样,只是参考分层压缩法进行操作,这样可以生成更加均匀的试样,demo如下:












































new def par    width=1.5    height= width      rdmax=0.009    rdmin=0.006        poro=0.25
   vsporo=1-(1-poro)*0.5
   cengshu=8.0end@pardomain extent [-height*2] [height*2]set random 10001wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5cmat default model linear method deformability emod 10e9 kratio 1.5def create_sample    loop n(1,cengshu)        dibuzuobiao=-width*0.5 height*(n-1)/cengshu        dingbuzuobiao=-width*0.5 height*(n)/cengshu          group_string=string.build("keli_%1",n)        jieguo_string=string.build("bushu_dist_%1",n)        command            wall delete walls range id 3            wall create id 3 vertices [-width*0.5*1.5] [dingbuzuobiao] [width*0.5*1.5] [dingbuzuobiao]            ball distribute porosity  @vsporo radius @rdmin box [-width*0.5] [width*0.5] ...                                                        [dibuzuobiao] [dingbuzuobiao] group @group_string            ball distribute porosity @vsporo radius @rdmax box [-width*0.5] [width*0.5] ...                                                        [dibuzuobiao] [dingbuzuobiao] group @group_string            ball attribute density 2.7e3 damp 0.7            cycle 2000 calm 50                        cycle 4000            save @jieguo_string        endcommand            endloopend@create_samplesolvesave sample_distribute_2_2


这里分8次distribute,每次状态为:


第一次:

image.png

第四次:


image.png

第八次:

image.png



最后状态为:

image.png

可以看出与单次distribute已经有了改善,这里分16次再算一次:

image.png


image.png




、超级快速成样方法——Brick方法


    分层可以使得试样均匀,这个道理PFC的开发人员当然也注意到了,于是开发了Brick算法。就像其意思一样,Brick方法是先生成满足条件的一个小块,然后用这个小块拼凑起整个模型。


这个东西牛逼的是计算速度,上面的分层法计算一次基本上都需要十几分钟左右,但是brick方法只需要1秒!


Brick分为两部分:

(1)首先生成基本的砖头,注意这里的domain必须是周期边界,并且大小就是砖头的大小

(2)之后利用brick关键词进行组装



































new def par    width=1.5    height= width       rdmax=0.009    rdmin=0.006        poro=0.25
   vsporo=1-(1-poro)*0.5
   lieshu=8.0
end@pardomain extent [-width*0.5/lieshu] [width*0.5/lieshu] [-height*0.5/lieshu] [height*0.5/lieshu] condition periodicset random 10001ball distribute porosity  @vsporo radius @rdmin box [-width*0.5/lieshu] [width*0.5/lieshu] ...                                                        [-height*0.5/lieshu] [height*0.5/lieshu]ball distribute porosity @vsporo radius @rdmax box [-width*0.5/lieshu] [width*0.5/lieshu] ...                                                        [-height*0.5/lieshu] [height*0.5/lieshu]cmat default model linear method deformability emod 10e9 kratio 1.5ball attribute density 2.7e3 damp 0.7cycle 2000 calm 50solvesave brick_samplebrick make id 1ball deletedomain extent [-height*5] [height*5] condition stopwall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5brick assemble id 1 origin [-width*0.5] [-height*0.5] ...            size [int(lieshu)] [int(lieshu)]solvesave sample_brick


运行后的试样为:

image.png



    这里因为一个brick的数目比较少,所以效果可能并不是很理想,但是已经比直接生成效果好很多了。对于大数目的均匀试样,brick无疑是个好方法



下面给个总结吧:



image.png

image.png

总的来说,对于颗粒不是特别多的试样,分层压缩法 会是一个比较好的选择;

对于颗粒很多的试样,Brick应该是第一选择


代码&命令PFC科普
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2022-07-18
最近编辑:2月前
lobby
硕士 |擅长颗粒流PFC
获赞 846粉丝 4704文章 83课程 21
点赞
收藏
作者推荐
未登录
1条评论
仿真秀0727144348
签名征集中
1年前
为什么我运行PFC2D5.0 wall generate box [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] expand 1.5时报错呢?报错说是“expand 1.5”这里是unsed parameter,是放大倍数的命令更换了吗?
回复 1条回复
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈