SPH算法的理论和实践(2)

本文介绍了SPH算法的具体实现过程,包括粒子属性的初始化、粒子密度与压强的计算、粒子受力分析及位置更新等内容,并提出了一种高效的邻域粒子搜索方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2单流体SPH算法实现

经过前一章的介绍,知道了SPH算法的原理,这一章我们介绍SPH算法的代码具体实现


2.1算法框架

SPH算法的思想是用粒子来模拟流体,其中粒子承载了各种属性(如 位置、速度、加速度、密度、压强等),通过不断更新粒子的属性(其实最终的目的就是为了更新粒子的位置),达到流体动态模拟的效果。而粒子的属性受其周围粒子的影响,一般通过光滑核函数 A(ri)=AjmjρjW(r⃗ r⃗ j,h) A ( r i ) = ∑ A j m j ρ j W ( r → − r → j , h ) ,来计算粒子的各种属性。

所以,SPH算法迭代的流程如下:

Created with Raphaël 2.1.2 初始化粒子属性 计算粒子密度ρ 计算粒子压强p 计算粒子受到的压力F_pressure 计算粒子的粘滞力F_viscosity 得到粒子的加速度 更新粒子的位置

算法框架如下:
1. 初始化粒子的位置、速度、加速度、静态密度。
2. 根据光滑核函数计算粒子的插值密度 ρ(ri) ρ ( r i )
3. 根据公式 pi=k(ρ(ri)ρ0) p i = k ( ρ ( r i ) − ρ 0 ) 计算粒子的压强
4. 根据光滑核函数以及以及前二步得到的密度 ρ(ri) ρ ( r i ) 和压强 pi p i ,计算粒子的压力 Fpressurei F i p r e s s u r e
5. 根据光滑核函数以及粒子的粘度系数 μi μ i 和粒子的速度 u⃗ i u → i 计算粒子的粘滞力 Fviscosityi F i v i s c o s i t y
6. 累加压力 Fpressurei F i p r e s s u r e 、粘滞力 Fviscosityi F i v i s c o s i t y 和重力 Fexternali F i e x t e r n a l 得到粒子的受力 Fi F i ,除于密度 ρ(ri) ρ ( r i ) ,进而得到粒子的加速度 a⃗  a →
7. 更新粒子的速度 u⃗ i u → i 、位置 r⃗ i r → i
8. 返回第二步,一直迭代。


2.2 寻找邻域粒子

我们知道,粒子的各种属性是由光滑核半径 h h 之内的邻域粒子的属性计算得到的,那如何找到这些邻域粒子呢?


这里写图片描述

最常规的思路是,计算两个粒子之间的距离d=rirj,如果 d<h d < h ,则代表两个粒子相互影响。
然而我们发现,用这种方式去搜索所有粒子的邻域粒子的话,其时间复杂度为 O(n2) O ( n 2 ) ,可见这种方式效率不高。那如何改进呢?

我们可以通过划分网格的方式搜索邻域粒子,如下图所示。以 h h 为网格长度划分网格,使得网格覆盖所有的粒子。这样搜索某一个粒子的邻域粒子时,只需要搜索器周围的9个网格,而无需遍历所有的粒子,大大增加的效率。


这里写图片描述


2.3算法实现

写了一个简单的示例程序,运行效果如下:


这里写图片描述

该demo中粒子的绘制是用OSG写的。如果只是为了研究SPH算法,其实不需要太关注粒子绘制的问题,OSG绘制粒子只需要给SPH提供一个函数接口——输入是所有粒子的坐标,输出就是OSG用自己的渲染线程把粒子绘制出来。所以,每次更新完粒子的位置都调用一次这个函数就可以了。

下面给出源代码:SPH

程序是用vs2010开发的,OSG库的版本是3.4.1,要跑起来得要配置一下OSG。另外,SPH算法都写在sph.h和sph.cpp这两个文件中。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值