简介
本作业主要实现了2D流体模拟,包括欧拉视角的流体模拟,以及混合欧拉-拉格朗日视角的流体模拟(包括PIC/FLIP/APIC三种方法)。该作业的主要目标是全面的理解流体模拟的技术细节。
技术细节
Advection
由于时间原因,欧拉方法中的advection采用了最简单的Semi-Lagrangian advection,backtrace采用2阶Runge-Kutta方法。
Pressure Projection
压强投影的部分是本作业探索的第一个重点。代码中实现了CG solver, Modified Incomplete Cholesky PCG solver[1] 以及 Mutigrid PCG Solver[2]。为了更方便的处理自由表面的情况,稀疏矩阵的存储没有采用课程中提到的Matrix Free的格式,而是采用了[1]中提到的存储Adiag, Ax, Ay三个数组的格式。
Extrapolate Velocity
自由表面流体模拟中,需要计算非流体区域的速度情况。这里参考了citadel同学的实现。
Grid-Particle Transfer
本作业探索的第二个重点是混合欧拉-拉格朗日视角的流体模拟。在维持原有的压强投影算法的基础上,将欧拉视角中的advection用particle来实现。代码中总共实现了PIC, FLIP, APIC[3]三种算法。与课上提到的cell-centered grid不同,代码中实现了MAC grid上的这三种算法的P2G以及G2P transfer。
Github repo
结果展示
Dam Break
dambreak场景分别模拟了Eulerian,PIC,FLIP, FLIP(blending=0.97) 以及 APIC的结果。
- Eulerian
- PIC
- FLIP
- FLIP0.97
- APIC
Sphere Fall
- APIC
存在的问题
- 在APIC算法的实现过程中,G2P需要计算N(x)的梯度[3],但是采用cell-centered grid中的4 * weigh * dpos * inv_dx的实现方法会计算到中途爆掉,所以使用了手动推导N(x)的梯度的方法。不知道这是原理上不成立还是自己的实现有一些问题。
- 使用APIC做出来的Sphere Fall场景流体的左边比又边下落得快很多,跟自己的直观认识不太匹配。理论上应该是对称落下的,这里也不太理解。
后记
对于物理模拟这一块我也算是零基础入门,感觉看懂理论和自己真正实现出来一个物理引擎还是拥有巨大的差距,实现上的困难也让我错过了HW1的ddl,还好这次算是勉强压哨绝杀了HW2。后续的话我会继续尝试用taichi实现一些3d的流体模拟以及MPM方法的模拟,有兴趣的小伙伴欢迎关注我的github一起学习讨论。有了阶段性的进展我也会持续在论坛中更新。
最后十分感谢胡老师这门课细致的讲解。我认为GAMES201最大的意义,是赋予了任何一个零基础但愿意学习物理模拟的人自学这个领域的能力和纵览这个领域的视野,这样有价值的课程在国内是特别少有的。
参考文献
[1] R. Bridson, Fluid simulation for computer graphics, Second Edition . USA: A. K. Peters, Ltd., 2015.
[2] A. McAdams, E. Sifakis, and J. Teran, “A parallel multigrid Poisson solver for fluids simulation on large grids,” in Computer Animation 2010 - ACM SIGGRAPH / Eurographics Symposium Proceedings, SCA 2010 , 2010, pp. 65–73.
[3] C. Jiang, C. Schroeder, A. Selle, J. Teran, and A. Stomakhin, “The Affine Particle-in-Cell Method,” ACM Trans. Graph. , vol. 34, no. 4, Jul. 2015, doi: 10.1145/2766996.