Range fish的使用
PFC的range包含了絕大部分的范圍使用,包括id、組、位置等。當然作為一個用戶自由度非常高的軟件,也提供了用戶自定義范圍的方法,也就是range fish。這里對其使用方法進行簡單的講解以及應用,主要應用場景應當是對組間接觸的賦值是非常有用的。
一、fish range 的用法
首先第一步需要構造一個fish函數,fish函數的命名格式為:
fish def IsInRange(pos,pointer)if ... thenIsInRange=trueelseIsInRange=falseendifend
其中IsInRange為fish的名稱,其中需要包括兩個傳入參數,第一個參數是pos,為元素的位置;第二個參數為元素指針。在函數中需要根據if判斷來設定函數的返回值是true還是false。
第二步就是使用
range fish @IsInRange
進行調用即可。下面舉幾個小例子。
二、篩選指定位置的小顆粒
這里我們首先生成隨機分布的0.3-0.8半徑的顆粒:
model newmodel domain extent -10 10ball generate number 100 radius 0.3 0.8 box -8 8 -8 8
然后定義我們需要的小顆粒的條件:
def IsSmallKeli(pos,pointer)if ball.radius(pointer)<0.5 & comp.x(pos)>0 thenIsSmallKeli=trueelseIsSmallKeli=falseendifend
ball group "small" range fish @IsSmallKeli
這里我們把半徑小于0.5,并且位置在坐標軸右邊的顆粒定義為small的分組。
效果如圖:
三、篩選圓筒右邊筒壁的面片
這里我們首先生成一個圓筒:
model newmodel domain extent -10 10wall generate cylinder base 0 0 -5 axis 0 0 1 height 10 radius 5
之后定義我們分類的fish函數:
def IsInRight(pos,pointer)if comp.x(pos)>0 & wall.facet.normal.z(pointer)=0 thenIsInRight=trueelseIsInRight=falseendifend
wall group "right" facet range fish @IsInRight
筒壁上面片應該滿足坐標大于0,并且面片法向的向量的z值為0。
效果如圖:
四、指定組間接觸
這個之前介紹過一個方法 《接觸分組賦值》,很明顯的是里面的方法異常的繁瑣,雖然我們常說的是不管黑貓白貓,抓住老鼠就是好貓。但是代碼整潔、易修改也是我們的目標。
這里介紹一下利用range fish 實現組件接觸的賦值。
首先生成顆粒,分成 small 、mid 、big三個組。
model newmodel domain extent -10 10wall generate box -5 5ball generate radius 0.1 0.4 number 150 box -5 5ball attribute density 2e3 damp 0.7ball group "small" range radius 0.1 0.2ball group "mid" range radius 0.2 0.3ball group "big" range radius 0.3 0.4
然后我們定義組內的接觸:
contact cmat default model linear property kn 1e7 ks 1e1 fric 0.5contact cmat add 1 model linear property kn 2e7 ks 1e1 fric 0.5 ...range group "small" match 2contact cmat add 2 model linear property kn 3e7 ks 1e1 fric 0.5 ...range group "mid" match 2contact cmat add 3 model linear property kn 4e7 ks 1e1 fric 0.5 ...range group "big" match 2
這里的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)thenIsSmallAndMid=falseexitendifIsSmallAndMid=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=mid")enddef IsSmallAndBig(pos,pointer)ball_pointer_1=contact.end1(pointer)ball_pointer_2=contact.end2(pointer)if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)thenIsSmallAndBig=falseexitendifIsSmallAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=big")enddef IsMidAndBig(pos,pointer)ball_pointer_1=contact.end1(pointer)ball_pointer_2=contact.end2(pointer)if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)thenIsMidAndBig=falseexitendifIsMidAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=mid","Default=big")end
里面用到了兩個函數,這兩個函數應該在上述函數前定義:
1、 IsWallPointer 用來判斷是否是墻體指針:
def IsWallPointer(pointer)if type.pointer.name(pointer) =="Facet" thenIsWallPointer=trueelseIsWallPointer=falseendifend
2、 IsBetweenGroup 用來判斷兩個顆粒是否分別屬于兩個分組:
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 thenIsBetweenGroup=trueexitendifif ball_group_1==group2 & ball_group_2==group1 thenIsBetweenGroup=trueexitendifIsBetweenGroup=falseend
然后我們進行接觸賦值:
contact cmat add 4 model linear property kn 5e7 ks 1e1 fric 0.5 ...range fish @IsSmallAndMidcontact cmat add 5 model linear property kn 6e7 ks 1e1 fric 0.5 ...range fish @IsSmallAndBigcontact cmat add 6 model linear property kn 7e7 ks 1e1 fric 0.5 ...range fish @IsMidAndBig
效果如圖所示:
可以發現的是組間的接觸分別給了三個數值,如預期一樣,證明使用這種方式加組間接觸參數是可行的。
附上分組給接觸完整的代碼:
model newmodel domain extent -10 10wall generate box -5 5ball generate radius 0.1 0.4 number 150 box -5 5ball attribute density 2e3 damp 0.7ball group "small" range radius 0.1 0.2ball group "mid" range radius 0.2 0.3ball group "big" range radius 0.3 0.4contact cmat default model linear property kn 1e7 ks 1e1 fric 0.5contact cmat add 1 model linear property kn 2e7 ks 1e1 fric 0.5 ...range group "small" match 2contact cmat add 2 model linear property kn 3e7 ks 1e1 fric 0.5 ...range group "mid" match 2contact cmat add 3 model linear property kn 4e7 ks 1e1 fric 0.5 ...range group "big" match 2def IsWallPointer(pointer)if type.pointer.name(pointer) =="Facet" thenIsWallPointer=trueelseIsWallPointer=falseendifenddef 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 thenIsBetweenGroup=trueexitendifif ball_group_1==group2 & ball_group_2==group1 thenIsBetweenGroup=trueexitendifIsBetweenGroup=falseenddef IsSmallAndMid(pos,pointer)ball_pointer_1=contact.end1(pointer)ball_pointer_2=contact.end2(pointer)if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)thenIsSmallAndMid=falseexitendifIsSmallAndMid=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=mid")enddef IsSmallAndBig(pos,pointer)ball_pointer_1=contact.end1(pointer)ball_pointer_2=contact.end2(pointer)if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)thenIsSmallAndBig=falseexitendifIsSmallAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=small","Default=big")enddef IsMidAndBig(pos,pointer)ball_pointer_1=contact.end1(pointer)ball_pointer_2=contact.end2(pointer)if IsWallPointer(ball_pointer_1) | IsWallPointer(ball_pointer_2)thenIsMidAndBig=falseexitendifIsMidAndBig=IsBetweenGroup(ball_pointer_1,ball_pointer_2,"Default=mid","Default=big")endcontact cmat add 4 model linear property kn 5e7 ks 1e1 fric 0.5 ...range fish @IsSmallAndMidcontact cmat add 5 model linear property kn 6e7 ks 1e1 fric 0.5 ...range fish @IsSmallAndBigcontact cmat add 6 model linear property kn 7e7 ks 1e1 fric 0.5 ...range fish @IsMidAndBigmodel gravity 9.8model solve
工程師必備
- 項目客服
- 培訓客服
- 平臺客服
TOP




















