Fluent UDF中沿指定方向获取邻接网格

有朋友问我Fluent UDF有没有宏可以沿着指定方向搜索到下一个邻接的网格?答案是No,没有现成的宏可以实现这个目的,但是我们可以写一个函数来手动实现。这个思路如下:对于当前的网格,我们可以利用c_face_loop宏配合C_FACE及C_FACE_THREAD宏,对当前网格的所有face进行循环,例如下图中的当前网格循环会有0,1,2,3四个face。然后我们再利用F_C0分别取这四个face的c0,将c0与当前网格比较,如果c0就是当前网格,那么邻接网格就是c1,反之,如果c0不是当前网格,那么邻接网格就是c0。这样,我们就能得到四个邻接网格,至于需要指定方向的邻接网格,可以将当前网格与这四个邻接网格的中心连成矢量,然后分别求这四个矢量与指定的方向矢量的夹角,哪个夹角最小就是我们需要的邻接网格。如果夹角对应的face恰好为边界面则没有邻接网格,函数返回c=-1,表示没有找到邻接网格。

                   

 

例子代码如下(VC++ UDF Studio 2022R1学术版上编译通过)

#include "udf.h"

extern "C"
{
    #include "sg.h" //INTERIOR_FACE_GEOMETRY宏和BOUNDARY_FACE_GEOMETRY宏需要此头文件
};

cat_t GetNextCellByCell(cat_t cur_cat,real NV_VEC(direction))  
{
    int i;
    real angle_min=180;  //较大的初始值
    real ds,A_by_es,NV_VEC(A),NV_VEC(es),NV_VEC(dr0),NV_VEC(dr1),NV_VEC(vector);
    cat_t NextCellAndThread={-1, NULL}; //用于存贮最终邻接网格

    c_face_loop(cur_cat.c,cur_cat.t,i) //对当前cell的所有face循环
    {
        face_t f=C_FACE(cur_cat.c,cur_cat.t,i);  //face的f
        Thread* tf=C_FACE_THREAD(cur_cat.c,cur_cat.t,i);  //face的Thread
        if(!BOUNDARY_FACE_THREAD_P(tf)) //如果是内部face
        {
            cell_t c0=F_C0(f,tf); //取face的c0
            Thread*t0 = THREAD_T0(tf);
            INTERIOR_FACE_GEOMETRY(f,tf,A,ds,es,A_by_es,dr0,dr1);
            if(cur_cat.c==c0)  //当前网格是face的c0,那么邻接网格就是c1
            {
                NV_V(vector, =, es); //vector为c0中心到c1中心的单位矢量
                real cos_angle=NV_DOT(direction,vector)/(NV_MAG(direction)*NV_MAG(vector)); //点积公式获取两个矢量夹角的余弦值
                cos_angle=MIN(1.0,MAX(-1.0,cos_angle)); //将范围限制在[-1,1],以免acos函数出错
                real angle=acos(cos_angle)/M_PI*180;  // 根据余弦值计算角度
                if(angle<angle_min)  //如果小于其它夹角,则就是我们要的cell
                {
                    angle_min=angle;
                    NextCellAndThread.c=F_C1(f,tf);
                    NextCellAndThread.t=THREAD_T1(tf);
                }
            }
            else  //当前网格是face的c1,那么邻接网格就是c0
            {
                NV_VS(vector, =, es,*,-1); //vector为c1中心到c0中心的单位矢量
                real cos_angle=NV_DOT(direction,vector)/(NV_MAG(direction)*NV_MAG(vector)); //点积公式获取两个矢量夹角的余弦值
                cos_angle=MIN(1.0,MAX(-1.0,cos_angle));  //将范围限制在[-1,1],以免acos函数出错
                real angle=acos(cos_angle)/M_PI*180; // 根据余弦值计算角度
                if(angle<angle_min)  //如果小于其它夹角,则就是我们要的cell
                {
                    angle_min=angle;
                    NextCellAndThread.c=F_C0(f,tf);
                    NextCellAndThread.t=THREAD_T0(tf);
                }
            }
        }
        else //如果是边界face
        {            
            cell_t c0=F_C0(f,tf); //取face的c0
            Thread*t0 = THREAD_T0(tf);
            BOUNDARY_FACE_GEOMETRY(f,tf,A,ds,es,A_by_es,dr0);
            NV_V(vector, =, es);  //vector为c0中心到边界face的单位矢量
            real cos_angle=NV_DOT(direction,vector)/(NV_MAG(direction)*NV_MAG(vector)); //点积公式获取两个矢量夹角的余弦值
            cos_angle=MIN(1.0,MAX(-1.0,cos_angle)); //将范围限制在[-1,1],以免acos函数出错
            real angle=acos(cos_angle)/M_PI*180; // 根据余弦值计算角度
            if(angle<angle_min)  //如果小于其它夹角,则没有下一个邻接网格
            {
                angle_min=angle;
                NextCellAndThread.c=-1;
                NextCellAndThread.t=NULL;
            }
        }
    }

    return NextCellAndThread;
}

DEFINE_SOURCE(test_source, c,t, dS, eqn)
{
    cat_t current_cat={c,t};
    real NV_VEC(search_dir);

    NV_D(search_dir, =, 1.0, 0, 0); //假设要搜索x正方向的邻接网格
    cat_t NextCellAndThread=GetNextCellByCell(current_cat,search_dir);

    dS[eqn] = 0.0;
    return 0.0;  //只是为了说明GetNextCellByCell函数用法,所以不加源项
}

以上GetNextCellByCell函数即实现了对当前网格沿着指定矢量方向direction搜索邻接网格的功能。其中cat_t为Fluent内置类型,定义如下,cat就是cell and thread的缩写,实际就是cell的序号和Thread合成一个结构体类型。

typedef struct cell_and_thread_struct
{
  cell_t c;
  struct thread_struct *t;
} cat_t;

 

注意:以上代码目前仅考虑了真串行,如果是假串行或者并行,还要考虑并行架构,以及跨计算节点去搜索邻接网格,更加复杂一些。

说到真串行假串行问题,这里补充一个小要点,现在新版本的串行都是1个并行节点实现的假串行,UDF编程时候需要考虑并行架构。如果要不考虑并行架构,必须利用VC++UDF Studio插件(https://vcudfstudio.github.io) 中的串行启动来实现真串行。具体可以参考另外一篇博文《Fluent真串行假串行的问题 (学UDF前须知)》。

https://www.cnblogs.com/SuperUDF/articles/15985376.html

posted @ 2022-03-09 16:54  SuperUDF  阅读(1266)  评论(0)    收藏  举报