本文描述在Fluent中实现监测物理量并在物理量达到设定值时终止计算。
之前有道友在群里问这个问题,有道友要案例,这里就举个简单的例子。
以一个简单的物理模型来描述整个过程。
如图所示的几何模型,直径20 mm,长度200 mm。左侧壁面温度500 K,其他壁面为绝热。初始温度为300 K,考虑瞬态热传导,当物体内部中心点处温度为420 K时停止计算。
网格尺寸采用1 mm,在SCDM中生成网格。
这里求解一个固体瞬态热传导问题,案例设置较为简单。
物理量的获取方式主要有两种:
Get_Report_Definition_Values
获取值其中第2种方式无需进行代码并行改造,且执行效率较高。关于利用UDF获取指定位置的物理量值,可参阅Fluent UDF获取指定位置的物理量:
这里采用第2种方式获取物理量。
Surfaces → New → Point...
创建点report-temperature
,后面在UDF中会用到程序主要完成3个工作:
如下面的代码,利用UDF宏Get_Report_Definition_Values
获取报告的值(关于此宏的用法,可参阅Fluent UDF获取指定位置的物理量),然后将获取的值与420比较(这里420为目标值),当该值大于等于420时,给标识参数interruptflag
赋值。这里的标识参数interruptflag
需要利用scheme语句rp-var-define
在计算之前创建。
使用 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 = %f\n",Temperature);
//将报告值与目标值420进行比较,若温度大于420,则给标记参数interruptflag赋值1,否则赋值0
if(Temperature >= 420 )
RP_Set_Integer("interruptflag",1);
else
RP_Set_Integer("interruptflag",0);
}
interrupt.scm
,该文件只有一条语句,用于定义标识参数interruptflag
。(rp-var-define 'interruptflag 0 'integer #f)
(set! mstop? #t)
代码准备完毕后,进入 Fluent 操作
File → Read → Scheme...
加载scheme文件interrupt.scm
Execute Commands
,点击New...
创建命令Execution Type
为 Execute RepeatedlyWhen
为 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。
当监测点温度超过420 K后,计算自动终止。
如下图所示。
直接使用 scheme+表达式要更简单一些,但个人总觉得 scheme 不优雅。
参考资料:
(完)