首页/文章/ 详情

145、UDF编译能过但是一算就崩的几大原因

7月前浏览1467

0.前言

前两天有同学在交流群里问:自己的UDF编译顺利、Load正常,但是一点击计算或者初始化,Fluent 就闪退、报错,控制栏出现The f1 process could not be started

 

实际上我们在文章九十三、Fluent 出现The f1 process could not be started怎么办??简单提过这个问题的原因,今天来详细分析一下


1.为什么编译没问题计算就错误

我们都知道如果在UDF中写错了代码,在Fluent编译时会出现错误提示,以便我们检查UDF代码。


比如下面报错信息提示我们第8行、第12行和第17行代码有问题


 


如果你的UDF编译完全通过,Fluent没有任何报错,但是只要你一使用这个UDF(如初始化或点击计算),Fluent就会立刻崩溃掉,并出现The f1 process could not be started。


 


这种情况的原因五花八门,但都可以总结成一个原因:UDF和Fluent就像一对情侣,假设为A和B,A承诺要给B一些东西(比如礼物、数据),但当B真的问A要时,A却给不了,关系自然就崩了。

 


可能是UDF给不了Fluent一些数据,也可能是Fluent给不了UDF想要的,总之是他们闹掰了,倒霉的是我们!!下面我们就详细说说可能出现的几种情况



2. UDM内存分配不足

最常见的崩溃原因,没有之一!


很多同学在UDF里定义了用户自定义内存(UDM)来存储一些中间变量,比如:


C_UDMI(c,t,0) = C_T(c,t);
 


但是使用UDM的前提是必须在Fluent里分配UDM,且分配的数量要 ≥ 你代码里用到的最大索引+1


在Fluent界面:Define → User-Defined → Memory,设置好你需要使用的UDM数量。 

 


为什么会崩?没有分配内存就访问C_UDMI(c,t,i),相当于访问了一个不存在的地址,程序直接seg fault。也就是UDF在计算过程中想要获得获得一些地址的数据,但是Fluent给不了。


注:如果你的UDF用到了5个UDM变量(索引0-4),那就至少分配5个UDM。宁可多分配也别少分配!


比如我分配了2个UDM内存,但UDF中使用到了C_UDMI(c,t,4)

 


编译没有任何问题

 


但我只要执行这个UDF,就会立刻崩溃掉。此时只能关闭Fluent,重新打开。

 


3.多相流线程获取错误

如果你的UDM 使用是正确的,多相流线程获取问题也是非常容易出错的地方。这其实也是多相流UDF最大的难点。


在多相流模拟中,每个相都有自己的线程(thread),如果你在主相的线程上 访问次相的数据,有些时候是没问题的,虽然你获得的数据可能是错误的,但并不会出现崩溃。实际上这种错误反而更危险,因为你不知道自己是错的

 


真正会出现崩溃的情况是,UDF想要数据但问错了人,本来应该问主相要数据的,却在mixture线程上要数据,但mixture线程上根本就没有这个数据,Fluent自然无法将数据返回给UDF,只能崩溃。感觉Fluent的情绪不太稳定,动不动就崩溃!!


比如多相流问题,主相和次相上都有体积分数,通过C_VOF(c, t)宏可以获取,但UDF非要在mixture线程上获取相体积分数,完整代码如下,其中d = Get_Domain(1)获取的是混合相的Domain,问题就出在这里。

















#include "udf.h"DEFINE_ON_DEMAND(on_demand_calc){  Domain* d;   Thread* t;  cell_t c;  d = Get_Domain(1);   thread_loop_c(t, d)  {    begin_c_loop(c, t)    {      real vof = C_VOF(c, t);    }    end_c_loop(c, t)  }}
 


最后一运行ON_DEMAN宏,Fluent还是崩溃


 



4. 多相流ID错误

这个问题和上一个属于难兄难弟,都是多相流带来的麻烦。


很多同学搞不清phase domain ID和phase index的区别,可能会导致UDF出现错误。 两者的区别我在UDF进阶课里面详细讲解过,并给出了小技巧,看过的同学基本上不会再犯这种错误。


UDF搞错ID号也会直接崩溃掉,比如Fluent里面设置了两相流,但是UDF非要问Fluent要第三相的数据。

实在没办法,只能崩溃给你看看,谁让你乱提要求的。


还是刚才的代码,d = Get_Domain(1)获取的是混合相的Domain。现在我们让d = Get_Domain(4),让UDF获取ID=4相的Domain,但实际上我们的多相流相ID最大只等于3。


 


UDF想要的数据没有找到,如果运行这段代码,还是会崩溃掉。


注:

一些同学会想当然的认为,相ID号是连续的,甚至认为ID号从1开始,依次类推。但实际上并非如此。ID号只能通过界面查看,没有规律可言。



5.边界条件ID错误

这个问题和多相流ID错误一样,都是UDF要数据找错地方了。相较于多相流ID号来说,边界条件ID不会让人那么混淆。我们可以直接在边界条件界面看到ID号


 

边界条件ID一般通过下面的语句来使用,比如上图中,如果你想获取top边界的数据,那你就需要将下面代码中的ID号设置为7。


Thread *thread = Lookup_Thread(domain, ID);
 



如果你设置的ID号不存在,虽然编译没有问题,但Fluent会崩溃。



6.特殊宏的使用

Fluent提供了很多便捷的宏,但有些宏使用时需要特别小心,尤其是那些涉及梯度计算的宏。


比如很多同学都会使用到的C_YI_G(c,t,i)质量分数梯度,使用这个宏时需要先输入文本控制命令:


(rpsetvar 'species/save-gradients? #t)
 


如果你不输入这段代码,Fluent就会崩溃。


对于常规梯度宏的使用也比较复杂,UDF进阶课中有一节课详细介绍了梯度宏的使用,感兴趣的同学可以看看。

 


除了梯度宏外还有一些其他宏的使用需要注意,比如我以前出错的问题,使用C_D(c, t)时,湍流模型必须为k-e模型。我在k-w模型中使用,编译正常,但一计算就会崩溃,最后才发现这个问题。


再比如:

  • C_YI(c,t,i)在非预混/部分预混模型中不可用

  • C_P_G(c,t)仅适用于基于压力的求解器

还有很多其他宏的注意事项,需要大家自己用的时候注意


7.原因总结

还是回到我们开头说的,UDF崩溃的根本原因通常是内存访问错误或数据未就绪。


我们可以按照下面的顺序进行初步排查:






UDM分配了吗?多相流线程获取对了吗?Phase ID用对了吗?边界条件ID正确吗?梯度宏可以安全使用吗?
 


当然,还有很多其他的情况会导致UDF运行崩溃,这里只给出几个很常见的原因,大家可以先依次排查一遍,先定位到错误的代码行,然后再修改  






来源:Fluent学习笔记
Fluent多相流UDF湍流控制
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-01-02
最近编辑:7月前
Fluent学习笔记
博士 签名征集中
获赞 182粉丝 592文章 226课程 5
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈