我有一个简单的程序,其核心是浮点的二维数组,据说代表了气体浓度,我一直在尝试提出一种简单的算法,该模型将模拟气体向外扩展,就像云一样,最终结束整个电网的气体浓度相同。
例如,给定的状态进展可能是:(为简单起见,使用int)
开始状态
0000000000009000000000000
算法通过1次后的状态
0000001110011100111000000
再过一秒钟,应提供一个5x5的网格,所有网格均包含值0.36(9/25)。我已经在纸上进行了尝试,但是无论如何尝试,我都无法绕过算法来做到这一点。
所以我的问题是,我应该如何着手尝试对该算法进行编码?我尝试了一些事情,应用了卷积,试图依次获取每个网格单元并将其分配给其邻居,但是它们最终都产生了不良影响,例如最终最终消耗的气体少于我最初使用的气体,或所有气体运动都在一个方向上,而不是从中心向外扩展。我真的无法全力以赴,也将不胜感激。
这是一个短暂的问题,因此您需要执行积分以将状态从时间t(n)提前到t(n + 1)。您显示了一个网格,但没有及时解决问题。您尝试过什么整合方案?明确的?隐含的? Crank-Nicholson?如果您不知道,说明您无法正确解决问题。
我真正喜欢的一本书是S.W. Patankar的"Numerical Heat Transfer and Fluid Flow"。现在有点过时了,但是我喜欢这种治疗方法。 29年后它仍然很好,但是自从我读了这个主题以来,可能会有更好的文本。我认为对于初次研究它的人来说是可以实现的。
无论您使用哪种算法,它都可能会帮助您double buffer您的数组。
典型的平滑效果将类似于:
begin loop forever
For every x and y
{
b2[x,y] = (b1[x,y] + (b1[x+1,y]+b1[x-1,y]+b1[x,y+1]+b1[x,y-1])/8) / 2
}
swap b1 and b2
end loop forever
初始设置在原点()的浓度为9,在所有其他正负坐标的浓度为0。
初始状态:0 0 0 0(9)0 0 0 0
查找下一个迭代值的算法是从与相邻邻居的原点和平均电流集中处开始。原点值是边界情况,并且在考虑原点值及其两个相邻点的同时进行平均值,即在3个值中取平均值。所有其他值均有效地取2个值中的平均值。
迭代1之后:0 0 0 3(3)3 0 0 0
在迭代2之后:0 0 1.5 1.5(3)1.5 1.5 0 0
迭代3之后:0 .75 .75 2(2)2 .75 .75 0
迭代4之后:.375 .375 1.375 1.375(2)1.375 1.375 .375 .375
您可以循环执行这些迭代。每n次迭代输出一次状态。您可以引入一个时间常数来控制多少次迭代代表一秒钟的壁钟时间。这也是整数坐标表示的长度单位的函数。对于给定的硬件系统,您可以凭经验调整此值。您还可以引入稳态公差值来控制程序何时显示“所有邻居值均在此公差范围内”或“两次迭代之间的值变化不超过此公差”,因此该算法已达到稳态解决方案。
concentration = startingConcentration/(2*iter + 1)**2
iter是时间迭代。因此,以您为例。
startingConcentration = 9 iter = 0 concentration = 9/(2*0 + 1)**2 = 9 iter = 1 concentration = 9/(2*1 + 1)**2 = 1 iter = 2 concentration = 9/(2*2 + 1)**2 = 9/25 = .35
您可以在每个“时间步长”之后设置数组的值