本文描述如何利用Fluent UDF获取指定位置的物理量。
在Fluent UDF中有很多方式可以获取计算区域内某位置的物理量。如想要获取计算域内某一特定坐标位置的物理量,可以使用宏CX_Find_Cell_With_Point
得到一个结构体变量,之后利用RP_CELL
及RP_THREAD
宏得到该点所对应的cell索引与Thread指针,再使用C_
类宏可以得到各种物理量。
此方法仅用于获取坐标点位置的物理量,无法获取区域内的物理量。若要获取区域内的物理量,则需要在区域Thread上进行循环遍历,其间可能涉及到全局约简操作,在应用中时常需要进行代码并行化改造,颇为麻烦。
本文提供一种简单的方式来实现对几何坐标或区域内的物理量提取。
利用到的核心宏为Get_Report_Definition_Values
,此宏可以读取在Fluent中定义的任何Reports。
这里举个简单的例子。如下图所示边长为1 m的正方形计算区域,获取中心位置的温度值(左下角点为坐标原点。材料介质为固体,只考虑内部的热传导。
网格尺寸采用20 mm,划分全四边形网格,如下图所示。
采用默认的固体材料参数,指定边界条件计算得到的温度分布如下图所示。
若要获取中心位置的温度,可以如下图所示创建一个Point。
此时可以对点所在的位置进行统计。如下图所示统计得到的温度值为398.5262 K。
利用UDF也可以该点处的温度值。如使用下面的UDF程序。
#include "udf.h"
#include "cxndsearch.h"
static ND_Search *domain_table = NULL;
DEFINE_ON_DEMAND(find_Temperature)
{
#if !RP_HOST
cell_t c;
Thread *t;
CX_Cell_Id *cx_cell;
real velocity;
real P[2] = {0.5, 0.5};
real P_Cell[2];
domain_table = CX_Start_ND_Point_Search(domain_table, TRUE, -1);
cx_cell = CX_Find_Cell_With_Point(domain_table, P, 0.0);
if (cx_cell)
{
c = RP_CELL(cx_cell);
t = RP_THREAD(cx_cell);
Message("Temperature = %f \n", C_T(c, t));
}
domain_table = CX_End_ND_Point_Search(domain_table);
#endif
}
编译加载并运行,结果如下图所示。
UDF得到的温度值与后处理得到的温度值存在细微差异。
如下图所示创建一个Point。
创建一个Report Definitions
编写下面的UDF程序。
DEFINE_ON_DEMAND(get_temp2)
{
int nrOfvalues = 0;
real *values;
int *ids;
int index;
int counter;
/*第二个参数指定为0,试算*/
int rv = Get_Report_Definition_Values("report-temperature", 0, &nrOfvalues, NULL, NULL, NULL);
// rv为0表示函数成功执行,nrOfValues为返回值的数量
if (rv == 0 && nrOfvalues)
{
Message0("Report definition evaluated at iteration has %d values\n", nrOfvalues);
// 为变量开辟内存
values = (real *)malloc(sizeof(real) * nrOfvalues);
ids = (int *)malloc(sizeof(int) * nrOfvalues);
// 再次调用宏以获取数据,values存储报告的值,ids为报告关联的区域id,index为迭代次数
rv = Get_Report_Definition_Values("report-temperature", 0, NULL, values, ids, &index);
Message0("Values correspond to iteration index:%d\n", index);
//循环的目的是输出所有的报告的值
for (counter = 0; counter < nrOfvalues; counter++)
{
Message0("report definition values: %d, %f\n", ids[counter], values[counter]);
}
// 释放内存
free(values);
free(ids);
}
else
{
// 未找到对应的报告,则返回值为1
if (rv == 1)
{
Message0("report definition: %s does not exist\n", "report-temperature");
}
else if (nrOfvalues == 0) //没有获取到值
{
Message0("report definition: %s not evaluated at iteration level\n", "report-temperature");
}
}
}
编译并加载UDF,测试运行后如下图所示。
采用此方式不仅可以得到指定点的物理量,还可以获取任何Report值,应用起来非常方便。实际使用的时候只需要替换上面代码中Report Definition的名称即可。
(完毕)