PFC的range包含了绝大部分的范围使用,包括id、组、位置等。当然作为一个用户自由度非常高的软件,也提供了用户自定义范围的方法,也就是range fish。这里对其使用方法进行简单的讲解以及应用,主要应用场景应当是对组间接触的赋值是非常有用的。
一、fish range 的用法
首先第一步需要构造一个fish函数,fish函数的命名格式为:
fish def IsInRange(pos,pointer)
if ... then
IsInRange=true
else
IsInRange=false
endif
end
其中IsInRange为fish的名称,其中需要包括两个传入参数,第一个参数是pos,为元素的位置;第二个参数为元素指针。在函数中需要根据if判断来设定函数的返回值是true还是false。
第二步就是使用
进行调用即可。下面举几个小例子。
二、筛选指定位置的小颗粒
这里我们首先生成随机分布的0.3-0.8半径的颗粒:
然后定义我们需要的小颗粒的条件:
这里我们把半径小于0.5,并且位置在坐标轴右边的颗粒定义为small的分组。
效果如图:
三、筛选圆筒右边筒壁的面片
这里我们首先生成一个圆筒:
之后定义我们分类的fish函数:
筒壁上面片应该满足坐标大于0,并且面片法向的向量的z值为0。
效果如图:
四、指定组间接触
这个之前介绍过一个方法 《接触分组赋值》,很明显的是里面的方法异常的繁琐,虽然我们常说的是不管黑猫白猫,抓住老鼠就是好猫。但是代码整洁、易修改也是我们的目标。
这里介绍一下利用range fish 实现组件接触的赋值。
首先生成颗粒,分成 small 、mid 、big三个组。
model new
model domain extent -10 10
wall generate box -5 5
ball generate radius 0.1 0.4 number 150 box -5 5
ball attribute density 2e3 damp 0.7
ball group "small" range radius 0.1 0.2
ball group "mid" range radius 0.2 0.3
ball group "big" range radius 0.3 0.4
然后我们定义组内的接触:
这里的match 2相当于5.0的and用法,之前的全局设置降低到局部,应当是更加方便的。
到这一步为止,如果我们运行的话,组间的接触应该都是默认default的kn=1e7。如图:
图中蓝色的都是组间接触。
我们按之前的概念,首先定义三个组间的fish函数:
IsSmallAndMid 、 IsSmallAndBig 、IsMidAndBig
def IsSmallAndMid(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsSmallAndMid=false
exit
endif
IsSmallAndMid=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=mid")
end
def IsSmallAndBig(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsSmallAndBig=false
exit
endif
IsSmallAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=big")
end
def IsMidAndBig(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsMidAndBig=false
exit
endif
IsMidAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=mid","Default=big")
end
里面用到了两个函数,这两个函数应该在上述函数前定义:
1、 IsWallPointer 用来判断是否是墙体指针:
2、 IsBetweenGroup 用来判断两个颗粒是否分别属于两个分组:
然后我们进行接触赋
效果如图所示:
可以发现的是组间的接触分别给了三个数值,如预期一样,证明使用这种方式加组间接触参数是可行的。
附上分组给接触完整的代码:
model new
model domain extent -10 10
wall generate box -5 5
ball generate radius 0.1 0.4 number 150 box -5 5
ball attribute density 2e3 damp 0.7
ball group "small" range radius 0.1 0.2
ball group "mid" range radius 0.2 0.3
ball group "big" range radius 0.3 0.4
contact cmat default model linear property kn 1e7 ks 1e1 fric 0.5
contact cmat add 1 model linear property kn 2e7 ks 1e1 fric 0.5 ...
range group "small" match 2
contact cmat add 2 model linear property kn 3e7 ks 1e1 fric 0.5 ...
range group "mid" match 2
contact cmat add 3 model linear property kn 4e7 ks 1e1 fric 0.5 ...
range group "big" match 2
def IsWallPointer(pointer)
if type.pointer.name(pointer) =="Facet" then
IsWallPointer=true
else
IsWallPointer=false
endif
end
def IsBetweenGroup(bp1,bp2,group1,group2)
ball_group_1=ball.group(bp1)
ball_group_2=ball.group(bp2)
if ball_group_1==group1 & ball_group_2==group2 then
IsBetweenGroup=true
exit
endif
if ball_group_1==group2 & ball_group_2==group1 then
IsBetweenGroup=true
exit
endif
IsBetweenGroup=false
end
def IsSmallAndMid(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsSmallAndMid=false
exit
endif
IsSmallAndMid=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=mid")
end
def IsSmallAndBig(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsSmallAndBig=false
exit
endif
IsSmallAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=big")
end
def IsMidAndBig(pos,pointer)
ball_pointer_1=contact.end1(pointer)
ball_pointer_2=contact.end2(pointer)
if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)then
IsMidAndBig=false
exit
endif
IsMidAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=mid","Default=big")
end
contact cmat add 4 model linear property kn 5e7 ks 1e1 fric 0.5 ...
range fish @IsSmallAndMid
contact cmat add 5 model linear property kn 6e7 ks 1e1 fric 0.5 ...
range fish @IsSmallAndBig
contact cmat add 6 model linear property kn 7e7 ks 1e1 fric 0.5 ...
range fish @IsMidAndBig
model gravity 9.8
model solve