1. SPH Kernel

常用的sph kernel函数如下式所示

c为归一化系数,对于1d sph 有:

对于2d sph有:

2d sph kernel的代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@ti.func
def sph_kernel(x : vec2, x0 : vec2):
r = (x - x0).norm()
r_div_h = r / h
r_div_h2 = r_div_h * r_div_h
r_div_h3 = r_div_h2 * r_div_h

rv = 0.0

if r_div_h < 1 / 2:
rv = 1 - 6 * r_div_h2 + 6 * r_div_h3
elif r_div_h < 1:
one_m_r_div_h = (1 - r_div_h)
rv = 2 * one_m_r_div_h * one_m_r_div_h * one_m_r_div_h
else:
rv = 0.0

return rv * c

对2d sph kernel求梯度有

python代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@ti.func
def gradient_sph_kernel(x: vec2, x0: vec2):
x_m_x0 = x - x0
r = x_m_x0.norm()

drdx = x_m_x0[0] / (r + 4e-3)
drdy = x_m_x0[1] / (r + 4e-3)

r_div_h = r / h

dSdr = 0.0

if r_div_h < 1 / 2:
dSdr = 18 / h3 * r * r - 12 / h2 * r
elif r_div_h < 1:
one_m_r_div_h = (1 - r_div_h)
dSdr = -6 * one_m_r_div_h * one_m_r_div_h / h
else:
dSdr = 0.0


return vec2(dSdr * drdx, dSdr * drdy) * c

Sph用采样点的加权平均作为函数估计值

对微分算子 ,由于Sph中只有 有关,因此

这对任意微分运算成立

通常,在估计梯度时,我们常常会用sph的拓展非对称形式和对称形式。由密度公式

非对称:

对称:

这两种形式不存在绝对的优劣。

一般在计算压力,作用力相关的物理量的时候会用对称形保证系统动量守恒。

2. wcsph weakly compressible smooth particle hydrodynamics

​ 2.1 理论

​ 在模拟流体模拟时,往往需要求解带不可压约束的navier-stokes方程

​ 在传统方法中,为了满足不可压约束往往会同过联立方程(1),(2)同时求解 同时更新压力和速度。具体做法为通过spliting把微分方程(1)分为两个部分 advection和projection,逐步求解方程。这些方程被称为advection-projection方法。其中projection涉及把空间离散化后建立稀疏矩阵并求解。

​ 此时,压强可以看成流体为了满足约束(2)产生的内力。这个过程中 为常量。

​ 可以看到,由于不可压约束,advection-projection多了求解线性系统这一复杂步骤。wcsph将不可压条件改为弱可压条件,避免了复杂计算。它将 删去,将压强建模为 ,其中 为rest状态下密度。方程变为,其中 为变量。

​ wcsph将空间离散化为一系列带属性的小粒子(定值粒子质量 ,粒子体积 变量:密度,速度,位置) 。该方法利用拉格朗日视角追踪粒子,通过sph方法采样空间中各种属性用以更新速度。算法为(其中):

1) 遍历所有粒子估计密度

  1. 遍历所有粒子估计压强

为了解决free surface边界条件,将 限制为大于0可以防止边缘的粒子密度太小导致压强为负

  1. 遍历所有粒子计算方程其余项:

这里用了 的拟合化形式 。

​ 4. 遍历所有粒子,带入方程,更新速度

2.2 踩坑

模拟过程中参数的一组合理值

时间步长对wcsph模拟稳定性至关重要。当 过大时会出现数值爆炸现象:

3 DFSPH (Divergence-Free Smooth Particle Hydrodynamics)

DFSPH提出了一种更稳定的流体模拟方法,它在wcsph给出的压力模型上修改压力计算方式,保证了系统的密度恒定以及速度散度恒定,从而使系统满足不可压约束。

*.1 Rigid-Fluid Coupling

Versatile Rigid-Fluid Coupling for Incompressible SPH提出了一种能同时模拟刚体和sph流体的方法,其方法核心为给刚体生成模拟粒子。在模拟过程中同时计算流体粒子和刚体粒子相互的作用力。

对于任意形状的刚体,作者用 Particle-Based Simulation of Granular Materials 中的方法生成粒子。具体做法为:

  1. 对于刚体表面(如三角网格),计算其sdf用于生成不同偏移参数下的粒子。
  2. 利用marching tetrahedra(2d 下为marching squre),为sdf表面生成三角形网格(2d下为线段)
  3. 对每个三角形(2d下为线段),在其内部等概率随机生成 个粒子其中 为密度参数 为粒子半径, 为三角形面积 (2d下为 其中 为线段长度)
  4. 调整粒子位置让其在网格表面分布均匀。做法为以速度 更新粒子位置。其中 为刚体的sdf场, 为sdf在 位置的法线。 为核函数(可选用sph函数)。 把更新后的粒子约束在sdf表面, 使粒子之间的距离尽可能的远。

利用该方法生成的圆形为:

在模拟刚体过程中,作者采用如下形式计算两个粒子之间的压强力:

对于刚体粒子j和流体粒子i。由于连续性,不妨令

对于 我们采用 计算。其中 为流体粒子在reference状态下的密度。 在由预计算提前计算。

虽然我们在生成粒子的过程中尽可能的保证了粒子的均匀分布。由于刚体表面的几何形式,仍会导致粒子在空间分布的不均匀。因此,在计算粒子体积时,可对密集区域的粒子分配较小体积,对稀疏区域粒子分配较大体积。体积的形式为:

其中 为刚体粒子k的邻域刚体粒子的sph核函数的加权平均。

对于处于液体刚体交界处的液体粒子i的压强 。其密度 需改写为

其中j为粒子i的液体粒子邻居,k为粒子i的刚体粒子邻居,

在实现时,若采用symetric form sph则其形式为:

实现后效果如下图所示,可以看到除了少部分高速粒子漏入刚体内部,大部分粒子都与刚体表面交互并被阻挡。

TODO: 摩擦力

对于刚体受力,可以累加各个刚体粒子受力,并将这些粒子的力和力矩累加作为刚体受力结果。