一般计算中,Fluent达到我们设定的残差值后就可以自动停止运算,但是有时候我们可能残差判断标准不一定是恒定的,或者有多款软件之间来回协同计算,那么就必须在Fluent UDF中判断残差标准是否达到然后停止计算,后面再进行其它UDF操作。我们知道,通常情况下开始迭代后,要停止计算只能按“Stop”按钮或者键入Ctrl+C组合键。这要改成在UDF中实现迭代停止就非常有难度了。
那么我们是否可以改一种思路呢?我们可以利用Execute_At_End宏在每次迭代(或时间步)结束时候判断是否满足残差标准,如果不满足就驱动fluent继续迭代1次,如果满足就不做任何操作,这样如果继续迭代,那么后面那次迭代完成后又会调用Execute_At_End宏判断是否继续更多一次的迭代,满足了就不做任何操作,相当于停止。于是这样循环往复就实现了迭代满足残差自动停止一样的效果。执行流程如下图所示。
其中,最核心的就是如何驱动Fluent迭代1次。这个可以借助VC++ Udf Studio插件来实现(注意,只有企业版有这个功能,学术版没有此功能)。
下面给出例子,该程序实现了当连续性方程的残差小于0.0001时停止计算。
//利用VC++ Udf Studio2022R1企业版编译通过
#include "udf.h"
#include "SuperUdfExtension.h" //迭代一次的函数声明在企业版拓展库头文件中
#pragma comment(lib, "SuperUdfExtension.lib") //迭代一次的函数实现在企业版拓展lib库中
#define CONTINUITY_RESIDUAL_TO_STOP 0.0001 //设置的停止迭代时的残差值
DEFINE_EXECUTE_ON_LOADING(load, libudf)
{
HMODULE hModule=AfxGetInstanceHandle(); //固定写法,参见企业编程手册
SuperUdf_Initialize(hModule); //拓展库的初始化,固定写法,参见企业编程手册
}
DEFINE_EXECUTE_AT_END(JudgeResidual)
{
real ContinuityRes=0; //连续方程的残差
Domain *domain=Get_Domain(1);
for(int i=0;i<DOMAIN_NUMEQN(domain);i++)
{
int eqn = DOMAIN_EQNS(domain,i); //方程序号
CString strEqnLabel=DOMAIN_EQN_LABEL(domain,eqn); //获取方程的名字
if(!strEqnLabel.IsEmpty()) //如果方程名字不为空
{
if(0==DOMAIN_RES_SCALE(domain,i))
DOMAIN_RES_SCALE(domain,i)=1.0;//防止分母为零
real scaled_res=DOMAIN_RES(domain,i)/DOMAIN_RES_SCALE(domain,i); //获取残差
if(0==strEqnLabel.CompareNoCase("continuity")) //如果是连续方程,则把残差赋值给ContinuityRes
ContinuityRes=scaled_res;
}
}
Message0("Continuity Equation Scaled Residual= %e \n", ContinuityRes); //打印到Fluent控制台
if(N_ITER<=1) //第1次的残差可能为0,不考虑残差而继续迭代
{
Message0("1st iteration, Continue to iterate\n");
SuperUdf_Steady_Iterate(1); //执行下一次迭代
}
else if(N_ITER>1 && ContinuityRes > CONTINUITY_RESIDUAL_TO_STOP) //第2次迭代开始再考察残差是否大于设置值,若大于则继续迭代
{
Message0("Residual> %g, Continue to iterate\n", CONTINUITY_RESIDUAL_TO_STOP);
SuperUdf_Steady_Iterate(1); //执行下一次迭代
}
else
Message0("Residual<= %g, stop iteration\n", CONTINUITY_RESIDUAL_TO_STOP);
}
在Visual Studio中按VC++UdfStudio工具条上的“编译”按钮直到编译通过,然后点“加载”按钮将编译好的UDF库加载到Fluent中。
加载成功后, 记得hook该Execute_at_end宏,如下。
然后,设置好case,并将迭代步数设为1次,再点击“Calculate”进行计算。
当连续性方程残差大于设定的值时会不断循环驱动Fluent迭代1次,而连续性方程残差条件满足时就停止继续迭代,执行效果如下图所示。
最后,需要说明一下的是,企业版试用版只能累计调用1次SuperUdf_Steady_Iterate(1)函数,如果你用企业试用版可能会出现如下提示。那是试用版缘故,不是例子源代码问题。因为第一次迭代结束就已经调用了1次SuperUdf_Steady_Iterate,当第二次迭代结束再调用时就超出了试用版的限制,因此警告后就自动停止了。