Windows 7
VS2013 WinForm
Emgucv
Activiz.Net
json.net
log4net
- 用DEM(Discrete Element Method)的方法对三维空间的小球进行随机堆积。在DEM每一步的迭代中,根据小球上一时刻的速度计算小球的位置,并对位置进行边界的限幅;利用上一时刻的加速度计算小球当前的速度,并计算小球计算小球受到的力,计算下一时刻需要用到的加速度。
- 项目支持两种不同的边界条件:立方体边界和圆柱体边界
- 半径是随机产生的,均匀半径是0.5,即边界的尺寸会随着需要堆积的小球的个数变大
- 可以在不同的边界条件下模拟小球的运动情况
- 可以将实时运动的情况以图像的形式保存在文件夹中
- 可以以txt形式保存实时的加速度、速度、位置以及小球的半径等
- 对于界面来说,窗体中的控件可以随界面大小的改变而改变;当小于初始大小时,控件大小恢复为初始状态,并加上scrollbar。
- 可以实时对小球的位置和半径进行实时保存,并可以从文件中导入小球的位置和半径,即可以在上一次的仿真的基础上继续仿真
- 小球的属性值是通过json文件进行导入与导出
- 在迭代的过程中,可以生成日志文件,记录当前的状态信息。
- 可以生成基于三维图像的切片序列,即用于三维重建。
- 设小球的边界为N_BASE,则在这里产生的小球的个数为
3*N_BASE*N_BASE*N_BASE
. - 划分立方体网格,在网格点的周围随机产生球心的位置,半径按照初始方法随机产生。
- 小球和边界碰撞后,法向的速度会有一定程度的衰减,切线速度保持不变;和小球碰撞以后,则小球的速度会有一定的衰减。
- 设圆柱的半径和高为R和H,小球的半径为r(这里是0.5),则小球的个数为
3*R*R*h/(4*r*r*r)
,即圆柱和小球的体积之比 - 小球的初始分布也是呈网格分布,在圆柱的地面的内切正方形内产生网格,高度即逐渐向上叠加,知道小球的个数达到要求为止。
- 这里小球碰到边界后也是法向方向上速度衰减,切线方向速度不变,计算小球碰撞后速度时需要用到坐标变换的东西。
- 点击
求解问题
按钮,则开始迭代求解,此时点击停止求解
,则停止迭代;在停止后,当前所有小球的状态会作为下次重新开始求解时小球的状态的初始值。
- 将操作需要单击的按钮改完菜单栏,通过点击菜单栏的选项可以实现多种功能的操作,之前的功能全部保留
- 添加了显示系统状态的文本框,显示系统目前正在进行的操作等
- 完善了日志的输出和结果的保存
- 问题1 : 显示体绘制的切片图像序列,会出现无法关闭该窗口,关闭主界面时,也会出现异常
- 解决办法:新建一个界面,在其中添加RenderWindowControl控件,用于显示切片图像序列的体绘制结果,关闭它时不会出现异常。
- 添加系统设置界面
- 支持容器的类型以及对应尺寸参数的修改,即修改系统中小球的个数
- 支持系统设置的存储,在初始化时,如果没有找到该配置文件,则采用程序中设置的默认参数
- 在对系统参数进行修改之后,无需重启系统即可直接基于新的设置参数进行模型求解等
- 添加json数据文件的回放功能
- 需求原因:小球个数比较多时,系统仿真较慢,在每次迭代时可以存储小球的位置等信息到数据文件,方便之后可以通过加载数据文件直接查看小球所在的位置并进行可视化
- 考虑到回放过程中,可能需要改变界面的大小等,因此将回放功能放到新建的线程中运行。
- 添加对小球能量的计算,即将所有小球的动能和重力势能进行求和,可以看出系统能量在迭代的过程中是逐渐减小的
- 迭代过程优化
-
时间比较(81个小球,2000次迭代)
每个小球都计算距离并判断是否相交:253574ms 每个小球只判断下标比它大的小球是否相交:193622ms 每个小球只计算与它距离小于一定阈值的小球是否相交:157743ms
-
- 问题1:在修改设置之后,即改变小球的个数,对应
RenderWindowControl
中RemoveAllViewProps
时会出现wglMakeCurrent failed in MakeCurrent()
的问题,查阅资料发现可能是驱动的问题。- 解决办法:在每次修改系统设置时,删除原来窗口中的
RenderWindowControl
控件,新建一个添加到其中,问题解决
- 解决办法:在每次修改系统设置时,删除原来窗口中的
- 问题2:添加新的线程之后,在关闭主界面时,线程有可能没有被关闭(CPU使用率高居不下。。。)
- 解决办法:将系统中新开的线程的BackGround设置为true即可,在关闭窗口的时候,其中所有开启的线程都会被关闭
- 其他
guide更新日期:2017.04.09
- 两个小球相交过大之后,不容易恢复
- 后来修复了小球之间相交时的受力计算的过程
- 同时修改了仿真时的部分参数,具体为:增大相交时的速度衰减系数,同时不对速度和加速度进行限幅
- 将所有的线程的状态设置为
Background
,确保在界面关闭时,所有线程也会随之关闭。
- 设置界面中可以设置系统的
timestep
,在初期可以将其设置的大一点(5e-4),加快迭代过程,在后期可以设置得小一点(1e-4左右),可以防止系统产生过于震荡 - 小球的类型被修改为只有单一粒径分布的三种情况,并且给出了这三种情况下对应的小球的位置和半径的精度,即将系统中导出的小球的半径与位置信息除以该精度值,得到信息以像素为单位,便于后续的分析与处理
- 设置界面中可以根据当前的粒径分布设置,显示将当前的位置与粒径信息转化为实际像素值的粒径信息所需要的信息
- 参数界面菜单栏下加入小球的沿径向计算孔隙率、沿堆积主轴方向(Z轴)计算孔隙率的选项
- 计算所有小球两两的距离,极大地加快了小球的迭代过程
- 计算4000个点之间的两两距离,普通的循环迭代需要
100s
,而加速方法只需要0.8s
- 这种方法对系统的内存有一定要求,当小球个数大于3800时,在8G内存的电脑下,也是有
out of memory
的异常
- 计算4000个点之间的两两距离,普通的循环迭代需要
- 引入小球的邻接小球的概念,对于某个特定的小球,不是所有小球都需要与之判断是否相交,只有靠近它的小球才需要判断是否需要计算距离。
- 在这里每隔100次迭代对小球的邻接小球数组(存储需要进行距离计算的小球的下标)进行更新,当小球之间的距离小于一定的阈值时,将其纳入计算范围。阈值的选取方式为
Th = 2 * timestep * MaxVel * 100
- 在这里每隔100次迭代对小球的邻接小球数组(存储需要进行距离计算的小球的下标)进行更新,当小球之间的距离小于一定的阈值时,将其纳入计算范围。阈值的选取方式为
- 为了加快小球的迭代过程,在初始时刻,给所有小球一个竖直向下的速度
V0=-20
,小球可以以很快的速度向下运动 - 初始化小球的位置时,在每一层产生互不相交的小球,同时保证在容器限定的
X-Y
平面内,这使得小球初始时刻的致密程度大大增加 - 对于每一次迭代过程,计算过程为
- 判断是否需要更新小球的邻接小球的下标信息,如果需要则更新
- 计算小球的受力
- 计算小球的速度
- 计算小球的位置
- 计算系统的能量
- 将所有小球限制在边界范围以内,即保证所有小球都是处于容器以内的(对小球的位置在
X-Y
平面做限幅操作) - 因为小球的位置初始化方式被改变,因此将所有小球的最大半径设置为0.5,同时移除了
centerbias、radiusbias
等之前的设计中比较麻烦的变量- 注:小球的半径发生变化,相当于其质量发生变化,小球下降的过程中,球与球之间以及球与墙壁之间的弹性系数也需要进行相应的改变,当前是比较合适的参数,之后如果修改最大半径,则弹性系数也需要做出相应的改变。
- 可以计算系统沿Z轴与径向孔隙率的分布,Z的大小确定方式为当前所有小球球心最大Z值的1/2,对于长方体容器,XY即其底部正方形,对于圆柱体边界,XY为其底部圆形的外接正方形
- 保存小球的位置和小球信息时,在
txt
文件中存储的半径和位置信息都是以um
为单位,方便后续的处理 - 将小球的孔隙率生成等耗时操作放在线程中,防止界面卡死