Fluent UDF 根据给定点坐标获取cell

很多朋友在开发Fluent模型中需要根据点的坐标来查找对应的cell。总体来说,有两种方法,一种是利用内置的函数来查找,另外一种就是自己写代码查找,这里逐一介绍。

1. 利用内置函数查找

Fluent有一个内置函数CX_Find_Cell_With_Point可以根据点坐标查询对应cell号码。原型声明如下,注意不同Fluent版本中参数有所变化。

CX_Cell_Id *CX_Find_Cell_With_Point(float v[3]);  // 对于Fluent version 6.3~12.1
CX_Cell_Id *CX_Find_Cell_With_Point(ND_Search *, float v[3]);  //对于 Fluent version 13.0
CX_Cell_Id *CX_Find_Cell_With_Point(ND_Search *, double v[3], double time); //对于Fluent version>=14.0

具体怎么用就直接上代码吧(本例利用VC++ UDF Studio插件编译通过(https://vcudfstudio.github.io),示例代码考虑了不同的Fluent版本,兼容所有Fluent版本)。

#include "udf.h"
extern "C"
{
#if RampantReleaseMajor>=13
    #include "cxndsearch.h"  //需要的头文件
#endif
};

DEFINE_ON_DEMAND(find_cell)
{
    cell_t c;
    Thread *t;
    real coord_Cell[ND_ND];  //找到的cell的中心坐标
    CX_Cell_Id* cx_cell = NULL;
    real Pt_to_find[3]={0.0, 0.0, 0.0}; //指定寻找点的坐标
#if RampantReleaseMajor>=14 // for Fluent >=14.0
    double Pt[3];
    ND_Search*domain_table = NULL;
    domain_table = CX_Start_ND_Point_Search(domain_table,TRUE,-1); //准备开始查找点
    NV_V(Pt, =, Pt_to_find);
    cx_cell = CX_Find_Cell_With_Point(domain_table, Pt, 0);    
#elif RampantReleaseMajor>=13  // for Fluent13.0
    float Pt[3];
    ND_Search*domain_table = NULL;
    domain_table = CX_Start_ND_Point_Search(domain_table,TRUE,-1); //准备开始查找点
    NV_V(Pt, =, Pt_to_find);    
    cx_cell = CX_Find_Cell_With_Point(domain_table, Pt);    
#else  // for Fluent6.3~12.1
    float Pt[3];
    NV_V(Pt, =, Pt_to_find);
    CX_Start_ND_Point_Search();//准备开始查找点
    cx_cell = CX_Find_Cell_With_Point(Pt);
#endif
    
    if (NULL != cx_cell)
    {
        c=RP_CELL(cx_cell); //找到的cell序号
        t = RP_THREAD(cx_cell); // 找到的cell线索
        C_CENTROID(coord_Cell,c,t);  //获取cell中心坐标
        Message0("coordinate of the specified point: x=%g,y=%g,z=%g\n",Pt_to_find[0],Pt_to_find[1],Pt_to_find[2]);
        Message0("coordinate of the cell found: x=%g,y=%g,z=%g\n",coord_Cell[0],coord_Cell[1],coord_Cell[2]);
    } 
    else
        Message("Could not find cell at [%g,%g,%g]!\n",Pt_to_find[0],Pt_to_find[1],Pt_to_find[2]);

#if RampantReleaseMajor>=13  // for Fluent >=13.0
    domain_table = CX_End_ND_Point_Search(domain_table);  //结束查找
#else
    CX_End_ND_Point_Search();  //结束查找
#endif
}

 

2. 自己写代码查找

自己写代码查找原理很简单,就是遍历计算区域内所有的cell,然后判断哪个cell中心到指定点坐标距离最小的即为找到的cell。以下是串行示例代码(并行还需进一步改进)。

#include "udf.h"

DEFINE_ON_DEMAND(find_cell)
{
    cell_t c;
    Thread *t;
    cat_t found_cell;
    real dist, min_dist=1E10;
    real xc[ND_ND],coord_Cell[ND_ND], NV_VEC(dist_vector);
    Domain*domain = Get_Domain(1);

    real Pt_to_find[3]={0.0, 0.0, 0.0}; //指定寻找点的坐标

    thread_loop_c (t,domain)
    {
        begin_c_loop(c,t)
        {
            C_CENTROID(xc,c,t);
            NV_VV(dist_vector, =, Pt_to_find, -, xc);  //从当前cell到指定查找点的矢量
            dist=NV_MAG(dist_vector); //获取矢量长度,即距离
            if(dist<min_dist)
            {
                min_dist=dist;
                found_cell.c=c;
                found_cell.t=t;
            }
        }
        end_c_loop(c,t)
    }

    C_CENTROID(coord_Cell, found_cell.c, found_cell.t);  // 获取找到的cell的中心坐标
    Message0("coordinate of the specified point: x=%g,y=%g,z=%g\n",Pt_to_find[0],Pt_to_find[1],Pt_to_find[2]);
    Message0("coordinate of the cell found: x=%g,y=%g,z=%g\n",coord_Cell[0],coord_Cell[1],coord_Cell[2]);
}

 

总体来说,第二种方法更加简单易懂,也不容易出错,但因为需要对所有cell进行循环,可能会浪费一些计算量,尤其不要放在迭代时每个cell都会调用一遍的宏中,比如DEFINE_SOURCEDEFINE_PROFILE等等。

posted @ 2022-02-27 10:55  SuperUDF  阅读(1363)  评论(0)    收藏  举报