Mar*_*sce 6 algorithm physics numerical-methods
我正在尝试使用一系列谐波振荡器对一维波进行简化模拟.根据教科书的说法x[i],第i个振荡器位置的微分方程(假设均衡x[i]=0)证明了这个:
m*x[i]''=-k(2*x[i]-x[i-1]-x[i+1])
(导数是时间)所以我试图用以下算法数值计算动力学.这osc[i]是第i个振荡器作为具有属性loc(绝对位置),vel(速度),acc(加速度)和bloc(平衡位置)的对象,dt是时间增量:
for every i:
osc[i].vel+=dt*osc[i].acc;
osc[i].loc+=dt*osc[i].vel;
osc[i].vel*=0.99;
osc[i].acc=-k*2*(osc[i].loc-osc[i].bloc);
if(i!=0){
osc[i].acc+=+k*(osc[i-1].loc-osc[i-1].bloc);
}
if(i!=N-1){
osc[i].acc+=+k*(osc[i+1].loc-osc[i+1].bloc);
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处查看算法,只需单击即可向第6个振荡器发出脉冲.你可以看到它不仅不会产生波浪,而且还会产生一个总能量增加的运动(即使我加了阻尼!).我究竟做错了什么?
所有给出的答案都提供了大量有用的信息。\n你必须做的是:
\n\nPS,您没有实现真正的隐式欧拉,因为它需要同时影响所有粒子。为此,您必须使用投影共轭梯度法,导出雅可比行列式并求解粒子串的稀疏线性系统。显式或半隐式方法将使您获得动画所期望的“跟随领导者”行为。
\n\n现在,如果您想要更多,我在 SciLab 中实现并测试了这个答案(懒得用 C++ 对其进行编程):
\n\nn=50;\nfor i=1:n\n x(i) = 1;\nend\n\ndt = 0.02;\n\nk = 0.05;\nx(20) = 1.1;\nxold = x;\nv = 0 * x;\nplot(x, \'r\');\nplot(x*0,\'r\');\nfor iteration=1:10000\n for i = 1:n\n if (i>1 & i < n) then\n acc = k*(0.5*(xold(i-1) + xold(i+1)) - xold(i));\n v(i) = v(i) + dt * acc;\n x(i) = xold(i) + v(i) *dt;\n end\n end\n if (iteration/500 == round(iteration / 500) ) then\n plot(x - iteration/10000,\'g\');\n\n end\n xold = x;\nend\nplot(x,\'b\');\nRun Code Online (Sandbox Code Playgroud)\n\n波的演变可以在下面的堆积图中看到:\n