找回密码
 注册
查看: 442|回复: 3

一种瞬态的粒子插入算法,可以满足瞬态成核条件下任意位置的粒子的模拟

[复制链接]
发表于 2026-8-31 10:03:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
做离散相模拟的朋友应该都遇到过这个问题——
你想模拟空化气泡的生成,但气泡该在哪冒出来?晶体该从哪析出?这些位置不是固定的,而是随流场瞬态变化的。
传统的做法是什么?手动划分几个 injection surface,硬编码几个位置,祈祷算出来的结果别太离谱。
但物理不是这样的。 真实场景中,成核位置是由局部压力、温度、相分数等条件实时决定的——它应该是一个动态筛选 + 随机采样的过程。
所以我写了 DynamicParticlesInjector。
它是怎么工作的?
整个算法分五步,逻辑非常直接:
第一步:各进程各自收集候选单元
每个并行进程遍历自己负责的网格,逐个检查单元是否满足用户设定的物理条件。比如"温度低于接近温度"——满足条件的,就把它的质心坐标存下来。候选数量不确定?没关系,数组初始分配 128 个位置,不够就翻倍扩容,总能装下。因此这个算法是不需要操心数组容量不够的问题,但如果网格容量比较大,还是建议给一个较大的值(2^n),避免多次翻倍。
第二步:所有候选坐标汇总到主节点
并行计算下,网格分散在各个计算节点上。主节点(进程 0)依次向其他节点发出信号,其他节点收到后将本地的候选坐标发回。一轮点对点通信下来,主节点就拿到了全场的候选池。
第三步:主节点随机采样
主节点从全局候选池中随机抽取指定数量(P_NUM)的位置。采样是有放回的——但在实际工程中,候选池动辄几十上百万个单元,只采十来个,重复概率极低(百万取十,重复概率约万分之一),完全可以忽略。如果候选单元数少于要采的粒子数,采样数会自动降为候选单元数,不会出错。
第四步:采样结果广播到所有节点
这一步是并行通信的关键。Fluent UDF 没有直接暴露 MPI 广播函数,那怎么让所有节点拿到相同的结果?这里用了一个稳定的技巧——全局求和代替广播:只有主节点持有采样坐标的值,其他节点对应位置全是零。对全体做一次 PRF_GRSUM,零加非零等于非零,所有节点就同时拿到了完全相同的坐标。这个方法在各个 Fluent 版本上都兼容,通信开销也微乎其微。
第五步:重定位粒子
每个节点拿到采样坐标后,遍历自己负责的注射源粒子——前 N 个粒子移到采样坐标上,多余的粒子标记移除。因为所有节点拿到的是同一组坐标,而 group/cone 注射源的粒子集中在同一个节点上,所以最终恰好有 N 个粒子被精确放置在采样位置,不多不少。
下一个时间步,整个过程重新来一遍。 候选池变了,采样位置跟着变,粒子的注入位置自然跟着流场走——这才是动态成核该有的样子。
核心优势
  • 无需预定义注入区域 — 粒子自动出现在满足物理条件的地方
  • 完全并行化 — 自动跨进程通信,大规模并行算例直接用
  • 一行代码定制条件 — 把 if (center[1] > 0) 换成你的判断,比如 C_P(c,t) < P_sat
  • 采样自适应 — 有效单元不够时自动降采样,不会报错
适用场景
空化成核、晶体析出、气泡生成、溶质沉淀——任何"核从哪里来"的动态成核问题。

                               
登录/注册后可看大图


 楼主| 发表于 2026-9-1 16:58:14 | 显示全部楼层
欢迎各种提问和留言
发表于 2026-9-2 11:50:51 | 显示全部楼层
这种方法能算出饱和空气的冷凝过程吗?

点评

理论上讲可以,这只是个可以在任意满足条件的网格内插入粒子的算法,只要插入条件设置得当并且粒子参数合适保证不发散即可  详情 回复 发表于 3 天前
 楼主| 发表于 3 天前 | 显示全部楼层
周华 发表于 2026-9-2 11:50
这种方法能算出饱和空气的冷凝过程吗?

理论上讲可以,这只是个可以在任意满足条件的网格内插入粒子的算法,只要插入条件设置得当并且粒子参数合适保证不发散即可
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表