简述PFC成样方法

    这部分内容包括:

    粒径放大法、压缩法、分层压缩、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:

简述PFC成样方法的图1

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

简述PFC成样方法的图2

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

(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里面可以看到指定数目的颗粒生成了

简述PFC成样方法的图3

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

简述PFC成样方法的图4

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

简述PFC成样方法的图5

一共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.5ball 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.7cycle 2000 calm 50cycle 4000save init_generate_quyuwall attribute yvel [-y_vel] range id 3solve time [height*(pengzhangxishu-1)/y_vel]wall attribute yvel 0 range id 3solvesave sample_generate_1_3

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

简述PFC成样方法的图6

压缩后的状态如图:

简述PFC成样方法的图7

    

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

(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次成样,下面给出执行中的试样状态:

第一次压缩:

简述PFC成样方法的图8

第四次压缩:

简述PFC成样方法的图9

第八次压缩:

简述PFC成样方法的图10

最后状态的试样为:

简述PFC成样方法的图11

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

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

简述PFC成样方法的图12

简述PFC成样方法的图13

    很多学者对于压缩时候的能量传递进行研究,认为由于压缩能的影响,下部的颗粒在成样的时候应该松一点,上部的颗粒应该密一点。这时候我们可以改变孔隙率实现这个想法,具体为:如分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


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

简述PFC成样方法的图14

进行平衡后的试样如图:

简述PFC成样方法的图15

(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,每次状态为:

第一次:

简述PFC成样方法的图16

第四次:

简述PFC成样方法的图17

第八次:

简述PFC成样方法的图18

最后状态为:

简述PFC成样方法的图19

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

简述PFC成样方法的图20

简述PFC成样方法的图21

三、超级快速成样方法——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.0end@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

运行后的试样为:

简述PFC成样方法的图22

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

下面给个总结吧:


简述PFC成样方法的图23

简述PFC成样方法的图24

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

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

(3条)
默认 最新
非常好
评论 点赞
评论 点赞

查看更多评论 >

点赞 7 评论 3 收藏 17
关注