本文描述在Fluent中实现监测物理量并在物理量达到设定值时终止计算。
之前有道友在群里问这个问题,然后我转载了一篇文章【仿真技巧】Fluent中基于某一计算结果实现软件停止计算。后台有道友要案例,这里就举个简单的例子。
1 问题
以一个简单的物理模型来描述整个过程。
如图所示的几何模型,直径20 mm,长度200 mm。左侧壁面温度500 K,其他壁面为绝热。初始温度为300 K,考虑瞬态热传导,当物体内部中心点处温度为420 K时停止计算。
网格尺寸采用1 mm,在SCDM中生成网格。
2 求解计算
这里求解一个固体瞬态热传导问题,案例设置较为简单。
2.1 General 设置
-
设置瞬态计算
2.2 Models设置
-
激活能量方程
2.3 Materials设置
-
设置材料参数
2.4 设置边界条件
-
指定高温壁面边界
2.5 监测物理量
物理量的获取方式主要有两种:
-
利用UDF直接获取指定位置的物理量 -
利用 Report 获取物理量。可以利用 UDF 宏 Get_Report_Definition_Values
获取值
其中第2种方式无需进行代码并行改造,且执行效率较高。关于利用UDF获取指定位置的物理量值,可参阅Fluent UDF获取指定位置的物理量:
这里采用第2种方式获取物理量。
-
右键选择模型树节点 Surfaces → New → Point...
创建点
-
定义想要检测的点的几何坐标
-
定义report监测中心点温度。注意report的名字 report-temperature
,后面在UDF中会用到
2.6 程序代码
程序主要完成3个工作:
-
获取report的值。 -
将获取的值与目标值进行比较 -
终止Fluent计算
如下面的代码,利用UDF宏Get_Report_Definition_Values
获取报告的值(关于此宏的用法,可参阅Fluent UDF获取指定位置的物理量),然后将获取的值与420比较(这里420为目标值),当该值大于等于420时,给标识参数interruptflag
赋值。这里的标识参数interruptflag
需要利用scheme语句rp-var-define
在计算之前创建。
-
UDF程序
使用 DEFINE_EXECUTE_AT_END
宏进行数据获取及判断工作。这里也可以使用 DEFINE_ADJUST
宏。
//control.c
#include "udf.h"
DEFINE_EXECUTE_AT_END(interrupt, d)
{
int nrOfvalues = 0;
real *values = (real *)malloc(sizeof(real) * nrOfvalues);
//获取报告的值,在Fluent中创建的报告的名字为report-temperature。参数1为瞬态计算中通过时间步长获取值
int rv = Get_Report_Definition_Values("report-temperature", 1, NULL, values, NULL, NULL);
//values[0]为报告返回值,注意返回值是一个数组,可能会有一系列的值
real Temperature = values[0];
Message0("current temperature = %fn",Temperature);
//将报告值与目标值420进行比较,若温度大于420,则给标记参数interruptflag赋值1,否则赋值0
if(Temperature >= 420 )
RP_Set_Integer("interruptflag",1);
else
RP_Set_Integer("interruptflag",0);
}
-
编写 scheme 脚本文件 interrupt.scm
,该文件只有一条语句,用于定义标识参数interruptflag
。
(rp-var-define 'interruptflag 0 'integer #f)
-
终止Fluent。终止Fluent计算过程可以使用下面的代码
(set! mstop? #t)
代码准备完毕后,进入 Fluent 操作
-
编译并加载 UDF
-
并利用菜单 File → Read → Scheme...
加载scheme文件interrupt.scm
-
右键选择模型树节点 Execute Commands
,点击New...
创建命令
-
在打开的命令定义对话框中进行如下图所示设置。 -
指定 Execution Type
为 Execute Repeatedly -
指定 When
为 Time Step -
定义命令为 (if (> (%rpgetvar 'interruptflag) 0)(set! mstop? #t))
这里的命令其实可以直接使用Scheme,不需要使用UDF。
如获取上面点point-3
的物理量,可以使用下面的代码
(pick-robust "/report/surface-integrals/ area-weighted-avg (point-3) temperature no" 1)
或者也可以写一个表达式获取report的值,将其命名为temp_monitor
,然后利用下面的代码获取值:
(pick-robust "/define/named-expressions/compute temp_monitor" 3)
然后利用获取的值,与420进行比较,替代上图中的interruptflag
。
如单纯使用表达式,可以写成这样(if (> (string->number (pick-robust "/report/surface-integrals/ area-weighted-avg (point-3) temperature no" 1)) 420)(set! mstop? #t))
:
注:这种方法不需要创建UDF,也不需要创建report,只需要创建一个名为point-3的几何坐标点即可。
”
或者写成这样:(if (> (string->number (pick-robust "/define/named-expressions/compute temp_monitor" 3)) 420)(set! mstop? #t))
注:这种方法不需要创建UDF,但需要创建一个report,其输出指定位置的物理量值。然后还需要创建一个表达式,表达式的名称为
temp_monitor
,其值为之前创建的report。”
2.7 初始化
-
初始化计算
2.8 进行计算
-
指定时间步数、时间等参数,进行计算
当监测点温度超过420 K后,计算自动终止。
如下图所示。
直接使用 scheme+表达式要更简单一些,但个人总觉得 scheme 不优雅。
相关链接:https://pan.baidu.com/s/1vzF7dP9HWiRUdgL91bAOhA?pwd=8xlb 提取码:8xlb
”
参考资料:
-
https://zhuanlan.zhihu.com/p/653370706 -
https://www.emdoor.cn/Res/view/id/286.html -
https://mp.weixin.qq.com/s/fwEuyk1qa8rxVjYO3wtfJQ
(完)
本篇文章来源于微信公众号: CFD之道
评论前必须登录!
注册