PFC双轴案例

目录

双轴压缩

伺服原理

参数化成样

应力计算并预压

加围压

重定义函数与加载


双轴压缩


伺服原理


        通过位移给墙体施加一个力。(墙体没有质量,只能根据重叠量来受力)

        使用墙给一个颗粒施加力

new

domain extent -10 10

ball create position 0 0 radius 1.0

ball attribute density 2e3 damp 0.7
ball fix vel spin
cmat default model linear property kn 1e7

wall create vertices -1 1 1 1
def cal_chongdie
    chongdieliang=1e4/1e7
end
@cal_chongdie
;计算重叠量
wall attribute yvel -1.0 range id 1 
;给一个y方向的速度

set timestep fix 1e-5
solve time [chongdieliang]

        使用墙给多个颗粒施加力

new

domain extent -10 10

ball create position -2 0 radius 0.5
ball create position -1 0 radius 0.5
ball create position -0 0 radius 0.5
ball create position 1 0 radius 0.5
ball create position 2 0 radius 0.5

ball attribute density 2e3 damp 0.7
ball fix vel spin
cmat default model linear property kn 1e7

wall create vertices -3 0.5 3 0.5
def cal_chongdie
    chongdieliang=1e4/(1e7*5)
end
@cal_chongdie
;重叠量为力除以刚度,墙体的力为1e4N
;一般不给试样施加力,施加应力
wall attribute yvel -1.0 range id 1 

set timestep fix 1e-5
solve time [chongdieliang]

        对上面的加载进行优化,使得cycle 1 步就能得到目标值。

new

domain extent -10 10

ball create position -2 0 radius 0.5
ball create position -1 0 radius 0.5
ball create position -0 0 radius 0.5
ball create position 1 0 radius 0.5
ball create position 2 0 radius 0.5

ball attribute density 2e3 damp 0.7
ball fix vel spin
cmat default model linear property kn 1e7

wall create vertices -3 0.5 3 0.5

def cal_chongdie
    chongdieliang=(1e4-0)/(1e7*5)
    sudu=chongdieliang/global.timestep    
    command        
        wall attribute yvel [-sudu] range id 1 
    endcommand
end
;对墙底施加速度
set fish callback 1.0 @cal_chongdie
;在时步计算之后进行回调
cycle 1

        球体串联情况

new

domain extent -10 10

ball create position 0 0 radius 1.0
ball create position 0 2 radius 1.0
ball attribute density 2e3 damp 0.7
ball fix vel spin range id 1
cmat default model linear property kn 1e7

wall create vertices -1 3 1 3

;k=k1*k2/(k1+k2)  
;k=k1/2
;串联时两个球体刚度计算
def cal_chongdie
    chongdieliang=1e4/(1e7*0.5)
end
@cal_chongdie

wall attribute yvel -1.0 range id 1 

set timestep fix 1e-5
solve time [chongdieliang]
wall attribute yvel -0.0 range id 1 
solve

        三角形分布球体伺服

        whilestepping,stop_me

new

domain extent -10 10

ball create position -1 0 radius 1.0
ball create position 1 0 radius 1.0

ball create position 0 [math.sqrt(3)] radius 1.0
;生成三个颗粒,根号3

ball attribute density 2e3 damp 0.7
ball fix vel spin range id 1
ball fix vel spin range id 2
cmat default model linear property kn 1e7

wall create vertices -1 [math.sqrt(3)+1] 1 [math.sqrt(3)+1]

;1、力小的时候,下压
;2、力大了,上浮
[wp=wall.find(1)]
;定义墙体指针
def get_force
    whilestepping
    wall_force=wall.force.contact.y(wp)
end
;whilestepping的效果和回调函数一样,即函数结果将会随着计算的更新而更新

def apply_vel
    whilestepping
    if wall_force<1e4 then
        wall.vel.y(wp)=-1.0
    else
        wall.vel.y(wp)=1.0
    endif    
end
;wall_force向上,为正值
;力小的话则墙体下压,否则墙体上浮

[stop_me=0]
def stop_me
    if math.abs(wall_force-1e4)<1 then
        stop_me=1
    endif
end
;stop_me函数判断截止条件,被solve调用,solve fishhalt @stop_me调用了停止函数
;当值为0时继续运行,当为1时停止运行


set timestep fix 1e-5
;时步不能太大,否则容易使得力来回变动
;solve fishhalt @stop_me  
cycle 1
;使用cycle 1 来打破平衡
solve
;两个要求,一施加力达到要求,二达到平衡

;cycle 2.2w

        伺服优化(速度+伺服系数)

new

domain extent -10 10

ball create position -1 0 radius 1.0
ball create position 1 0 radius 1.0

ball create position 0 [math.sqrt(3)] radius 1.0

ball attribute density 2e3 damp 0.7
ball fix vel spin range id 1
ball fix vel spin range id 2
cmat default model linear property kn 1e7

wall create vertices -1 [math.sqrt(3)+1] 1 [math.sqrt(3)+1]

;1、力小的时候,下压
;2、力大了,上浮
[wp=wall.find(1)]
def get_force
    whilestepping
    wall_force=wall.force.contact.y(wp)
end

[g=5e-4]
def apply_vel
    whilestepping
    vel=g*math.abs(wall_force-1e4) ;速度=伺服系数乘以力的差值
    if wall_force<1e4 then
        wall.vel.y(wp)=-vel
    else
        wall.vel.y(wp)=vel
    endif    
end

[stop_me=0]
def stop_me
    if math.abs(wall_force-1e4)<1 then
        stop_me=1
    endif
end


set timestep fix 1e-5
;solve fishhalt @stop_me 
cycle 1
solve

;g=1e-3 cycle 5k8
;g=1e-2 波动 不平衡 伺服系数g不能太大
;g=5e-3 cycle 1w4
;g=2e-3 cycle 2w2
;g=5e-4 cycle 1w4
;伺服系数需要试算

        试算伺服系数

new

domain extent -10 10

ball create position -1 0 radius 1.0
ball create position 1 0 radius 1.0

ball create position 0 [math.sqrt(3)] radius 1.0

ball attribute density 2e3 damp 0.7
ball fix vel spin range id 1
ball fix vel spin range id 2
cmat default model linear property kn 1e7

wall create vertices -1 [math.sqrt(3)+1] 1 [math.sqrt(3)+1]

;1、力小的时候,下压
;2、力大了,上浮
[wp=wall.find(1)]
def get_force
    whilestepping
    wall_force=wall.force.contact.y(wp)
end

;重叠量=力除以刚度
;速度=重叠量除以时步
[servo_factor=0.8]
def get_g
    ct_wp=contact.find("ball-facet",1)   
    gangdu=contact.prop(ct_wp,"kn")
    g=1.0*servo_factor/(gangdu*global.timestep)  
end
set fish callback 1.0 @get_g

def apply_vel
    whilestepping
    vel=g*math.abs(wall_force-1e4)
    if wall_force<1e4 then
        wall.vel.y(wp)=-vel
    else
        wall.vel.y(wp)=vel
    endif    
end

[stop_me=0]
def stop_me
    if math.abs(wall_force-1e4)<1 then
        stop_me=1
    endif
end


set timestep fix 1e-5
;solve fishhalt @stop_me 
cycle 10
solve

参数化成样


        加载板和试样之间的摩擦力为0,而颗粒与颗粒之间为0.5。(两者摩擦力取最小值)

new
def par
    width=0.4
    height=width*2
    
    rdmin=0.006
    rdmax=0.009
    
    poro=0.12
end
@par
;给出需要的参数

domain extent [-width*2.0] [width*2.0] ...
        [-height*2.0] [height*2.0]
set random 10001
;给定一个random的数值,使得每次运行得到的结果相同

wall generate box [-width*0.5] [width*0.5] ...
            [-height*0.5] [height*0.5] expand 1.5
;把边缘坐标进行放大(把加载板稍微加大一点)
ball distribute porosity @poro radius [rdmin] [rdmax] box ...
    [-width*0.5] [width*0.5] [-height*0.5] [height*0.5] 
ball attribute density 2e3 damp 0.7
cmat default model linear method deform emod 100e6 kratio 1.5
;method可以用来定义一些宏观的参数,但emod即弹性模量,但是弹性模量也会自动被计算为刚度
cycle 2000 calm 50
;让cycle尽量大,使得颗粒散开
ball property fric 0.5
;最好给出fric
solve
save sample

应力计算并预压


        预压模拟的是土体的先前条件伺服频率

        对于墙体和颗粒接触,模量乘以2对应kn的数值。

restore sample

[txx=1e4]
[tyy=1e4]
def wall_ini
    wpup=wall.find(3)
    wpdown=wall.find(1)
    wpleft=wall.find(4)
    wpright=wall.find(2)
end
@wall_ini
;使用指针找到墙体

def computer_chicun
    wlx=wall.pos.x(wpright)-wall.pos.x(wpleft)
    wly=wall.pos.y(wpup)-wall.pos.y(wpdown)
end
;计算尺寸
def computer_stress
    computer_chicun
    wyss=0.5*(wall.force.contact.y(wpdown)-wall.force.contact.y(wpup))/wlx
    wxss=0.5*(wall.force.contact.x(wpleft)-wall.force.contact.x(wpright))/wly
end
;计算应力,两侧应力的平均值

;伺服
[servo_factor=0.8]
def get_g

    zongKNY=100e6*2.0  ;假设初始时有一定的约束,防止颗粒过于松散,kn为0
    loop foreach ct wall.contactmap(wpup) ;遍历,ct为临时变量,它会把墙体接触依次定义
        zongKNY+=contact.prop(ct,"kn")   ;总的竖向刚度,
    endloop
    loop foreach ct wall.contactmap(wpdown)
        zongKNY+=contact.prop(ct,"kn")
    endloop
    
    zongKNX=100e6*2.0
    loop foreach ct wall.contactmap(wpleft)
        zongKNX+=contact.prop(ct,"kn")
    endloop
    loop foreach ct wall.contactmap(wpright)
        zongKNX+=contact.prop(ct,"kn")
    endloop
    
    gx=1.0*servo_factor*wly/(zongKNX*global.timestep) 
    ;wly表示对应的面积,把应力转化为力
    gy=1.0*servo_factor*wlx/(zongKNY*global.timestep)
    ;当试样特别松散的时候,刚度可能出现为0的情况
    ;时步正比于(质量/刚度)  
end

[sevro_freq=100] ;定义伺服频率,以步数作为跨度,隔一定步数计算函数
[time_record=global.step-1]
def sevro_walls
    computer_stress
    if global.step>time_record then
        get_g
        time_record=global.step+sevro_freq   ;每100步计算一次get_g
    endif    
    yvel=gy*math.abs(math.abs(wyss)-tyy) ;竖向速度
    if math.abs(wyss)<tyy then
        wall.vel.y(wpup)=-yvel
        wall.vel.y(wpdown)=yvel
    else
        wall.vel.y(wpup)=yvel
        wall.vel.y(wpdown)=-yvel
    endif  
    xvel=gx*math.abs(math.abs(wxss)-txx)    ;横向速度
    if math.abs(wxss)<txx then
        wall.vel.x(wpleft)=xvel
        wall.vel.x(wpright)=-xvel
    else
        wall.vel.x(wpleft)=-xvel
        wall.vel.x(wpright)=xvel
    endif  
end

set fish callback -1.0 @sevro_walls 
history id 1 @wxss
history id 2 @wyss
;记录x和y方向应力的变化
cycle 10
;多运行几下,打破平衡
solve
save yuya

加围压


        利用callback和fish函数

restore yuya
;采用伺服原理
[txx=100e3]
[tyy=100e3]
;设置为100kpa
;改变txx和tyy会直接代入yuya命令部分的函数进行计算
;因为callback存在,所以运行过程中会不断更新数值

cycle 1
solve

save weiya

重定义函数与加载


        对于预压部分的伺服函数进行重定义,删掉竖向伺服,添加竖向墙体速度。同时设定hist并添加加载截止条件。

restore weiya

ball attribute displacement multiply 0
;将位移进行清零
def sevro_walls
    computer_stress
    if global.step>time_record then
        get_g
        time_record=global.step+sevro_freq
    endif  
    ;获得g这个伺服系数
    xvel=gx*math.abs(math.abs(wxss)-txx)
    if math.abs(wxss)<txx then
        wall.vel.x(wpleft)=xvel
        wall.vel.x(wpright)=-xvel
    else
        wall.vel.x(wpleft)=-xvel
        wall.vel.x(wpright)=xvel
    endif  
    ;关掉竖向伺服,给竖向一个速度,墙体的下压与上浮
end
[strainRate=1e-2]
wall attribute yvel [strainRate*wly] range id 1
wall attribute yvel [-strainRate*wly] range id 3
;用应变率×尺寸作为速度

[Iy0=wly]
[Ix0=wlx]
;记录初始的宽度和高度
def computer_strain
    weyy=(Iy0-wly)/Iy0
    wexx=(Ix0-wlx)/Ix0
    wevol=weyy+wexx
;体变等于两个方向应变相加
end
set fish callback -1.0 @computer_strain
history delete 
;删除之前的一些历史记录然后重新定义
history id 1 @wxss
history id 2 @wyss
history id 3 @weyy
history id 4 @wexx
history id 5 @wevol

[stop_me=0]
def stop_me
    if weyy>0.2 then
        stop_me=1
    endif
end
solve fishhalt @stop_me
;人工定义截止条件,当应变大于0.2时就停止
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值