【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone.

一、问题背景

接上一篇文章【fluent】The fluent process could not be started,解决了上一篇文章的问题后,又发现了新问题。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第1张图片

Error: eval: unbound variable
Error Object: 

此错误的发生时机——在初始化设置中选择Compute From对象后就报错。

忽略这个错误可不可以呢?不清楚,不过如果我忽略后,强行初始化,就又会报错

Error: Flow boundary zone found adjacent to solid zone.
       This problem MUST be fixed before solution proceed
Error Object: #f

我原本以为这两个错误是独立开,需要分别解决的,但后来发现按照unbound variable错误的解决逻辑,最后能够解决Flow boundary zone found adjacent to solid zone.的错误

二、已尝试和实际有效方法(2.3.3有效)

2.1 检查名称或参数中是否带有空格

Ref:FLUENT 6 - One of the common reasons for ‘Error: access: unbound variable ; Error Object: phase-domain?’-Eureka.im

系统默认生成的区域名称、边界名称、材料名称、Report definition名称(统称为Object Name)都不可能是带有空格的,在不同字段字符串之间至少用连字符(-)或下划线(_)联结在一起。

然而有些用户在重命名已有object或添加新object(例如点线面、报告监测、云图、动画)时,喜欢用空格分开不同字段,这就导致了unbound variable的错误。

在fluent udf代码编写过程中,同样也不要有空格在宏名称、数据变量、标识符中。

2.2 在UDF中检查是否有变量未初始化/定义

错误的描述就是——未绑定的变量,猜测可能是因为UDF中的一些变量没有被正确初始化/赋值/定义。

诚如cfd-online上Martin在帖子Error: eval: unbound variable中的回答。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第2张图片
因为我是UDF初学者,虽然对官方文档较为熟悉,但是总归是有些地方理解不透。

对于全局变量在UDF的运行原理,我看不懂;花钱请网上UDF专家回答时,他也不那么确定。

因此我这里假设上面定义的全局变量(下图中的黄色三角所指的bou_temp)无效,再在profile边界条件宏中增添温度变量的定义。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第3张图片
重新编译libudf共享库,在fluent中重新加载,初始化选择compute from对象时,仍然出错。

2.3 检查UDF中profile宏是否有逻辑上的错误

为什么我重点检查profile宏呢?下图是UDF宏的执行顺序,没计算的时候,profile宏(边界条件宏)和初始化宏、材料宏就都会执行了。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第4张图片

因为我出错的时机发生在初始化选择compute from对象时,这个时候我还没有计算,也就不涉及我在我的UDF中定义的source源项宏和DEFINE_EXECUTE_AT_END宏。

而我没有定义初始化宏,也没有定义材料宏,因此只需要检查profile宏有没有出错。

而如果你是初始化过程中发现没问题,计算也没问题;在最后出问题的,那么你就需要重点检查DEFINE_EXECUTE_AT_END宏。

现在我们理清楚自己需要检查什么后,我们仔细检查profile宏(边界条件宏)。

notes:下面的bou_temp变量是在全局区域定义的,属于全局变量,因为我们需要通过全局变量和高级通信宏(node to host和host to node宏)实现host节点和node节点之间对于某些关键数据的通信;另外下面的代码中省略了包括头文件的codes,希望各位读者周知。

2.3.1 检查发现并不是逻辑判断问题

在profile宏中,原先其中包括如下代码

    if(time<7200 || time==7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<18000 && time==18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<28800 && time==28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;

我发现time<18000 && time==18000等地方有逻辑错误,再加上对C语言的巩固学习发现可以直接用<=、>=这种运算符号,就改成如下形式。

    if(time<=7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<=18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<=28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;

仍然无济于事!

2.3.2 node to host real是否不能出现在节点编译器指令中

原本我将node to host高级通信宏放在#if !RP_HOST…#endif中,但其实这个高级通信宏本身就有识别效果,无需定义编译器指令,将其放在编译器指令里面,还是外边,其实是无关紧要的,此处仅是作为一种尝试。

DEFINE_PROFILE(Inlet_Temp, t, i)
{
    #if !RP_HOST
    face_t f;
    real time = CURRENT_TIME;

    if(time<=7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<=18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<=28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;

    begin_f_loop(f, t)
    {
        if (PRINCIPAL_FACE_P(f, t))
        {
            F_PROFILE(f, t, i) = bou_temp;
        }
    }
    end_f_loop(f, t)
    #endif
    node_to_host_real_1(bou_temp);
}

结果发现还是出错——unbound variable。

2.3.3 是否node to host real不能出现在profile宏中

【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第5张图片
在将node to host real删去后,代码改成如下形式。

DEFINE_PROFILE(Inlet_Temp, t, i)
{
    #if !RP_HOST
    face_t f;
    real time = CURRENT_TIME;

    if(time<=7200)
    {
        bou_temp = 300 + 0.025*time;
    }
    else if(time>7200 && time<=18000)
    {
        bou_temp = 480;
    }
    else if(time>18000 && time<=28800)
    {
        bou_temp = 480 - (time-18000)/60;
    }
    else 
        bou_temp = 300;

    begin_f_loop(f, t)
    {
        if (PRINCIPAL_FACE_P(f, t))
        {
            F_PROFILE(f, t, i) = bou_temp;
        }
    }
    end_f_loop(f, t)
    #endif
}

这次就没有任何问题了。虽然在profile宏中删掉了bou_temp变量从node传到host的通信宏,但是我在后面的DEFINE_EXECUTE_AT_END宏里增加了node to host real通信宏,也能够将node里计算出来的bou_temp变量传到host节点中。

所以此处删除,并无大碍。

由此可见,大概profile宏是无法使用node to host real通信功能的,大多数场合其实也不需要在profile宏中通信。一般是在ADJUST宏、DEFINE_EXECUTE_AT_END宏中定义这种通信。

最终能解决问题,我很开心哇!!!解决问题的过程非常曲折,我也没想到profile宏竟然无法使用node to host real通信功能,而这一点我并没有在官方文档中看到很清楚的描述(官方文档的代码示例中只是没有在profile宏里用高级通信,有一定的暗示,但并没有明文说明),只是自己通过一点点的尝试,终于拿到了解决问题的钥匙。

此文章过于啰嗦,希望各位读者谅解本人的愚笨。我在这篇文章中基本总结了网上对此错误的解决方案,并且对我解决问题的全思路进行了分析,希望各位读者耐心阅读下去。

2.4 其他UDF编写优化方法

(1)能不用RP变量就不用RP变量,例如获取flow-time,宁可使用CURRENT_TIME也不要用RP_Get_Real(“flow-time”)间接获取,后者在并行UDF中不稳定。
(2)静态关键字要谨慎使用,也即少用static int a,而用int a是较好的选择。

三、其他可能的解决办法

本章节描述并非我出错的场景中适用的解决办法,例如3.1中是存储空间不足的情况,我没有这个问题,所以没写在第二部分。

3.1 读入完整无损的data文件

Ref:Fluent 计算中出现问题求助-小木虫

因为存储空间不够而导致data文件写入不完整,加载不完整data文件时,就会出现unbound variable的错误。

出现这种情况,只好依次加载计算过程较前阶段产生的data文件,将文件占用大小较为合理的data文件载入。

3.2 相同或更高版本的fluent软件打开算例

Ref:fluent出现 以下错误,unbound variable-知乎-上坡的人

如果某一个算例是较高版本fluent创建的,但是你用低版本的fluent读取,就可能出现unbound variable的错误。

最好用相同版本的fluent读取算例,其次才是用较高版本的fluent打开较低版本的算例,这样才最不容易出错。

另外,能先启动fluent软件再加载算例文件,就不要通过双击(或右键打开)的方式直接加载算例文件,因为如此可能导致较低版本的求解器加载算例文件。详见下篇ansys论坛中由ecrod发起的一则讨论How to solve “unbound variable error”。

【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第6张图片
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第7张图片
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第8张图片

3.3 将DOS脚本文件转为Linux脚本文件

Ref:nusit-FAQ: Fluent & CFX

如果你的算例中用到了脚本文件,那么你可能需要将DOS脚本文件转为Linux脚本文件,来避免出现unbound variable错误。

原文如下图。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第9张图片
以下是译文:

当你将脚本文件用于批处理 Fluent 作业时,在Windows/DOS上创建的Fluent脚本可能无法正常工作——发生unbound variable错误。

在这种情况下,你需要检查并将脚本文件从 Windows/DOS 文本文件转换为Unix/Linux文本文件。例如,你可以在 Linux 命令行提示符下执行以下操作:

> file run1.txt
run1.txt: ASCII text, with CRLF line terminators

> cat -v run1.txt 
rcd test.cas.gz^M
it 500^M
... 

> dos2unix -o run1.txt
dos2unix: converting file run1.txt to UNIX format ...

> file run1.txt
run1.txt: ASCII text


> cat -v run1.txt 
rcd test.cas.gz
it 500
...

使用 dos2unix 命令将文件转换为纯ASCII文本文件后,你会注意到文件格式将得到更正。通过file命令去除CRLF换行符,通过cat -v命令行去除结尾处的“^M”。

更正文件格式后,你再次提交作业,应该就可以正常工作。

3.4 Scheme相关问题

Ref:SCRIPTS, JOURNALS, UDF, FIELD FUNCTIONS

如果你用到了Scheme相关功能,可能会因为scheme代码不符合规范而出现unbound variable错误。

最常见错误——命令需要参数但是输入中没有绑定参数时。

例如执行(display (get-thread-list))会导致以下错误

Error: eval: unbound variable
Error Object: name

这是因为get-thread-list命令需要给一个命名规范参数,例如(display (get-thread-list '*shadow))命令就表示打印所有区域的名称,前缀是shadow。

再举一个例子,执行命令(scale-grid)会报错

Error eval: unbound variable
Error Object: fx

而执行命令(scale-grid 0.01)会报错,只不过第一个没补充的参数变成了fy,所以报错信息如下

Error eval: unbound variable
Error Object: fy

3.5 一些玄学解决思路

(1)重启fluent软件,重新加载算例,再来一次操作
(2)甚至更深程度地重启——电脑或云计算重新启动后,再进行(1)

如果你实在找不到错误原因,你可以去试试玄学真传中的秘籍。

四、关于标题的第2个错误

我在上文第一部分中就说了第一个错误解决后,第二个错误也会顺带解决。

但是当时我不知道这个逻辑的时候,专门去解决第二个错误—— flowchat boundary zone found adjacent to solid zone.,却没有得到我想要的答案。

网上关于这个错误的解决办法,无非就是将区域由固体属性改成流体属性。

但是我觉得这个解决办法太过荒谬——材料都改了,最终能算出自己想要的结果吗?

因为原先我是在流固耦合交界面上对流体和固体都划分了膨胀层,如下图所示,怀疑如此会导致错误,就单独创建一个简单的算例(仅仅给流体侧划分边界层)去验证,发现与错误并无关系。
【Fluent】Error: eval: unbound variable、Error Object;Flow boundary zone found adjacent to solid zone._第10张图片

你可能感兴趣的:(fluent,udf,Ansys,Workbench,fluent)