模拟两个球体碰撞经典力学

时间:2016-10-10 07:33:37

标签: fortran collision-detection simulation fortran90

我试图通过使用经典力学方程来模拟Fortran 90上两个球体的碰撞。

首先,我在一个维度上这样做:我正在将一个球体固定在地面上并将另一个球体固定在一定高度(两者都在t = 0处静止),并且它们都具有相同的半径和质量。

因此,作用于运动粒子的力是重力和弹力(当球体开始碰撞时)。因此,首先,移动球体仅受到重力,即Fg = -g.m.我只考虑一个维度,因此粒子下降会使我的值低于开始时的高度,因此。现在,当移动粒子击中固定粒子时,后者将产生Fe = -k.dx.n的力,其中k是弹性常数,dx是重叠,n是该力的方向(其范数是1)。弹力恢复,因此它也应该。需要说明的是,dx = r1 + r2 - | x1 - x2 |并且n =(x1-x2)/ | x1 -x2 |,其中r1,r2是半径,x1,x2是粒子在给定时间的位置。

代码编译好 ,唯一的问题是当我去检查移动粒子的位置时 - 有时,它会不断降低 (首先应该如此)然后 继续 减少到负值 - 这是不应该发生的事情。或者,当移动的球体 反弹到它应该的位置时,它会回到更高的高度而不是初始条件(它弹跳更高,违反能量守恒)。

事情就是,最佳情况它似乎正在起作用(最后一个,它弹跳更高),弹力的公式实际上是不对的(我把dx = r1 + r2 - | x1 + x2 |,而不是减号)。我已经尝试通过改变一些参数(降低和增加弹性常数并降低时间步长)来修正更高的反弹,但没有成功。此外,我提到的较高的弹跳大约高出四倍,因此不是计算错误的一些问题。

以下是代码的重要部分:计算力的位置和时间积分:

coef1 = abs(1.0d0*x1 - 1.0d0*x2)
coef2 = (1.0d0*x1 - 1.0d0*x2)/coef1
Fx_elasticaparcial(m) = -1.0d0*k*((1.0d0*a1+1.0d0*a2) + 1.0d0*coef1)*coef2
Fx_elasticatotal(l) = 1.0d0*Fx_elasticatotal(l) +1.0d0*Fx_elasticaparcial(m)

forcax(l) = 1.0d0*flagx(l)*(1.0d0*gravidade(massadummy)+1.0d0*Fx_elasticatotal(l))

m 是部分弹力, l 是施加在粒子上的总弹力(我已经考虑过在路上添加更多粒子)

function gravidade(massa)
use parametros, only: g
implicit none
real*8 :: gravidade, massa
gravidade = -1.0d0*g*massa
end function gravidade

这是一个引力的函数

subroutine integracaoEuler (xo, xn, vxo, vxn, fx, mass)
use parametros, only: N, dt
implicit none
real*8 :: xo, xn, vxo, vxn, fx, mass

xn = 1.0d0*xo + 1.0d0*dt*vxo
xo = 1.0d0*xn
vxn = 1.0d0*vxo + 1.0d0*dt*((1.0d0*fx)/(1.0d0*mass))
vxo = 1.0d0*vxn

return

end subroutine integracaoEuler

Euler整合子程序

do while ((t + dt) < (tmax)) !time loop
    t = t+dt
    do i = 1, N !particle loop
        do j = 1, N !neighbours of i particle loop
            if (i .NE. j) then
                if (abs(SQRT(1.0d0*xold(i) - 1.0d0*xold(j))**2) .LE. 1.0d0*a(i) + 1.0d0*a(j)) then
                    call forcastotais (i, j, m(i), a(i), a(j), xold(i), xold(j))
                else
                    forcax(i) = 1.0d0*flagx(i)*gravidade(m(i))
                end if
            end if
        end do
        call integracaoEuler (xold(i), xnew(i), vxold(i), vxnew(i), forcax(i), m(i))
        write(i, *) t, xold(i)
    end do
end do

程序的主循环

很抱歉让这个真的很大,修复它可能一定很容易。同样,我需要真正使用经典力学的方程式,而不是通过在碰到另一个球体或那种东西时将速度改变方向。我对此感到沮丧,并且不知道如何修复它(我已经坚持了2周)。我已经完成了我正在使用大量粒子制作的模型上的所有其他东西(粘度,细胞链接),但这个问题不断出现并弄乱了我的图形。欢迎任何帮助;请明确,因为我是编程新手。提前谢谢。

0 个答案:

没有答案