一、问题背景
前一段时间在闲鱼上,遇到有一个人问我“在udf中如何实现某一个变量满足一定取值范围内才保存dat和case文件”。
而后我帮他解决了这个问题,在此处也将解决办法公益性地分享出来。
主要参考的是CFD online上的一篇讨论fluent udf, saving data in udf。有一个答案答得很好,但是有一些细节仍然不够完善。
二、问题解决过程思路分析
假设条件是“求解过程中的变量满足某一个取值范围”,例如某一个面上的面积权值平均温度大于500K时就写出一个dat和case文件保存到本地。
要保存dat和case文件,有GUI和TUI的方法。
GUI的方法就不啰嗦了,大多数的人都懂。GUI的方式,也分为两种,一种是手动在file菜单中write写入,另一种是在calculate activity中双击autosave,设置自动保存。
遗憾的是,这个自动保存只能设置间隔一段时间或一些时间步保存一次,无法根据变量求解情况进行保存。
TUI的方法,就是利用/file/write-case和/file/write-case-data命令,在console窗口中输入后回车。
UDF中,有没有什么宏或者函数能实现如此功能呢?
我们翻阅官方文档,可以看到有以下几个宏与dat、case文件有关。
- DEFINE_EXECUTE_AFTER_CASE/DATA:在读取cas、data文件后执行这个宏里面的命令。
- DEFINE_RW_FILE:这个宏用于往dat文件中写入一些变量数据,但是执行这个宏时并不是保存/写入dat文件。
- DEFINE_RW_HDF_FILE:这个宏跟2一样,只不过是写入HDF类型的dat文件,相比传统dat文件占用更低的内存空间和更快的加载速度,但是兼容性很差,其他软件(CFD-POST、TECPLOT…)可能打不开。新版本的Fluent默认保存HDF类型的,你可以在preference中修改成legacy类型。
遗憾的是,TUI并不能访问求解过程中的变量数据,而UDF中也没有非常直接的能调用TUI命令的方式。
三、解决办法
3.1 定义scheme变量
首先你需要在fluent的console窗口中定义一个scheme变量。
(rp-var-define 'var_name 0 'integer #f)
上面的意思是说,将var_name 这个变量初始化赋值为0,它是整数类型。
scheme变量可以说是(在我印象中)唯一一个可供TUI和UDF交互的方式。
UDF中可以调用在console窗口中定义的scheme变量,并且修改它们。
3.2 在UDF中编写的代码
下面UDF的意思是,满足条件就将var_name这个scheme变量赋值为1。
if (condition==ok)
{write_data = 1;}
else
{write_data = 0;}
RP_Set_Integer ("var_name", write_data);
3.3 在fluent的GUI界面中需要执行的操作
在左边模型树中,双击Calculation Activities。
接着创建一个execute commands。
这个execute commands,会在每一次迭代步/时间步结束时触发,或者每隔1s触发。
我们在command输入框中粘贴如下形式的代码。
(if (= (%rpgetvar 'var_name) 1) (ti-menu-load-string (format #f "fi wcd your_case_name.cas.h your_case_name.dat.h")))
下面我来讲讲这一串代码的含义。
先用一张总图表示,如果你看明白,你就是大聪明。
- 在 Fluent 中,
wcd
是一个 TUI(Text User Interface)命令,用于将当前的案例(包括网格和边界条件等信息)和数据(如场数据)写入文件。这两个文件分别具有.cas
和.dat
扩展名。 fi
是一个缩写,表示 “file interpret”。fi
命令用于读取并执行包含 Fluent 命令和 Scheme 表达式的文件。由于ti-menu-load-string
的参数是一个字符串,因此需要使用fi
命令将wcd
命令作为一个字符串传递。这使得 Fluent 可以解释并执行这个字符串中的命令。fi
命令告诉 Fluent,将紧随其后的字符串作为一个命令来解释和执行。- 在 Scheme 语言(Fluent 使用的脚本语言之一)中,
format
函数用于创建格式化字符串。format
函数可以将字符串中的占位符替换为指定的值。函数的第一个参数决定了输出的类型,#f
表示将结果作为字符串返回,而不是直接输出到控制台或文件。在某些情况下,您可能需要使用format
函数来插入动态值,例如当前的时间步长或迭代次数,相应的自动编号规则是%t表示迭代步数、%f是流动时间、%s是时间步数。
如果你不加自动编号规则,那么每次 执行这个命令就会产生覆盖效果,你只能得到最后保存的数据和案例文件。
欲知后事如何,请听下回分解