【fluent UDF】保留UDM变量Reserving UDM Variables Using Reserve_User_Memory_Vars-测试分析篇

一、问题背景

因为对Reserve_User_Memory_Vars这个函数比较陌生,在学习官方文档过程中发现难以理解,于是只好亲手在fluent 2022上测试一番。

直接上结论:

此保留函数运行一次后(设置GUI界面中的UDM数目+第一次加载共享库成功),再如何运行都不会产生保留效果,因此我估计fluent中目前最多加载两个共享库。

二、测试1:

在官方2023的二次开发文档中,如下是保留函数功能的示范性代码。
在这里插入图片描述

/* general FLUENT header files */
#include "udf.h"
#include "para.h"
#include "mem.h"

static int udm_offset = UDS_UNRESERVED;
#define N_TESTLIB_UDS 2
#define NUM_UDM 4


DEFINE_EXECUTE_ON_LOADING(on_loading, libname)
{
    
    
    // if I_AM_NODE_ZERO_P
    // {
    
    
        if (udm_offset == UDM_UNRESERVED) 
            udm_offset = Reserve_User_Memory_Vars(NUM_UDM);
        if (udm_offset == UDM_UNRESERVED)
            Message("\nDefine %d extra UDMs in GUI and reload %s\n,and the UDM_UNRESERVED is %d\n", NUM_UDM, libname, UDS_UNRESERVED);
        else
        {
    
    
        Message("%d UDMs have been reserved by the current "
        "library %s\n", NUM_UDM, libname);
        Set_User_Memory_Name(udm_offset,"lib1-UDM-0");
        Set_User_Memory_Name(udm_offset+1,"lib1-UDM-1");
        Set_User_Memory_Name(udm_offset+2,"lib1-UDM-2");
        }
        Message("\nUDM Offset for Current Loaded Library = %d",udm_offset);
    // }
}

DEFINE_ON_DEMAND(set_udms)
    {
    
    
        Domain *d;
        Thread *ct;
        cell_t c;
        int i;
        d=Get_Domain(1);
        if(udm_offset != UDM_UNRESERVED)
        {
    
    
            Message("Setting UDMs\n");
            for (i=0; i<NUM_UDM; i++)
            {
    
    
                thread_loop_c(ct,d)
                {
    
    
                    begin_c_loop(c,ct)
                        {
    
    
                        C_UDMI(c,ct,udm_offset+i)=2.0+i/10.0;
                        }
                    end_c_loop(c,ct)
                }
            }
        }
        else
            Message("UDMs have not yet been reserved for library 1\n");
    }

在on loading宏里面,首先进行第一个if判断,由于初始化时将udm_offset变量赋值为UDS_

UNRESERVED(此预定义宏在sg_udms.h中定义,取值恒为-1),也即-1,所以判定为真,会执行保留函数。
在这里插入图片描述
但是保留函数会对UDMs进行判断,如果用户并没有在GUI界面中如下图所示设置UDM的数目,那么保留函数并不会生效。
在这里插入图片描述
因此还会进入第2个if判断,从而弹出错误——Define xx extra UDMs in GUI and reload xx1,and the UDM_UNRESERVED is xx。意思是说需要在GUI界面定义至少xx1个UDM.
在这里插入图片描述
因此我们在GUI界面中定义UDM后,再返回重新加载libudf共享库。

这次没有报错,console中输出信息如下(本人将NUM_UDM宏改成4了)。之所以会输出这么多条message,是因为本人用的是并行UDF,每条对应1个计算节点/核心。

4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

UDM Offset for Current Loaded Library = 0  4 UDMs have been reserved by the current library libudf

我们可以看出执行保留函数后,UDM Offset变量被复制为NUM_UDM的取值,因此得以进入else语句输出【4 UDMs have been reserved by the current library libudf】

而我们再重新编译一份UDF,代码和上面的差不多,命名为libudf2,加载过程中发现这次保留函数压根就没有生效。

/* general FLUENT header files */
#include "udf.h"
#include "mem.h"

static int udm_offset = UDS_UNRESERVED;
#define N_TESTLIB_UDS 2
#define NUM_UDM 4


DEFINE_EXECUTE_ON_LOADING(on_loading, libname)
{
    
    
    if (udm_offset == UDM_UNRESERVED) 
        udm_offset = Reserve_User_Memory_Vars(NUM_UDM);
    if (udm_offset == UDM_UNRESERVED)
        Message("\nDefine %d extra UDMs in GUI and reload %s\n,and the UDM_UNRESERVED is %d\n", NUM_UDM, libname, UDS_UNRESERVED);
    else
    {
    
    
    Message("%d UDMs have been reserved by the current "
    "library %s\n", NUM_UDM, libname);
    Set_User_Memory_Name(udm_offset,"lib2-UDM-0");
    Set_User_Memory_Name(udm_offset+1,"lib2-UDM-1");
    Set_User_Memory_Name(udm_offset+2,"lib2-UDM-2");
    }
    Message("\nUDM Offset for Current Loaded Library = %d",udm_offset);

}

DEFINE_ON_DEMAND(set_udms)
    {
    
    
        Domain *d;
        Thread *ct;
        cell_t c;
        int i;
        d=Get_Domain(1);
        if(udm_offset != UDM_UNRESERVED)
        {
    
    
            Message("Setting UDMs\n");
            for (i=0; i<NUM_UDM; i++)
            {
    
    
                thread_loop_c(ct,d)
                {
    
    
                    begin_c_loop(c,ct)
                        {
    
    
                        C_UDMI(c,ct,udm_offset+i)=2.0+i/10.0;
                        }
                    end_c_loop(c,ct)
                }
            }
        }
        else
            Message("UDMs have not yet been reserved for library 2\n");
    }

上面是libudf1的代码

在这里插入图片描述
下面是console中的输出信息,可以看出这次保留函数并没有生效。

UDF Autorun:
on_loading

Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Done.

Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

UDM Offset for Current Loaded Library = -1
Define 4 extra UDMs in GUI and reload libudf1
,and the UDM_UNRESERVED is -1

三、测试2:在加载libudf之后执行demand宏,再加载libudf1

官方文档中如是言:

Note:that the on demand UDF must be executed after the solution is initialized to reset the initial values
for the UDMs.
中文:注意demand udf必须在求解器初始化之后被执行以初始化UDM数值。

于是乎我这次没直接加载libudf1,而是在加载libudf之后执行demand宏,再加载libudf1。

结果仍然没有变化,保留函数仍然没有生效。
在这里插入图片描述

四、测试3:修改UDM的数目后再加载

我怀疑是不是每加载一次共享库就需要重新确定GUI界面中的Number of User-Defined Memory Locations。
在这里插入图片描述
于是我更改了数目(情况1),或者直接点开这个对话框不修改数目(情况2),再次确定。

这两种情况都已经测试,结果相同,都还是出现上面的问题。

五、无关紧要的并行化测试

其实在中途,我还将# if RP_NODE宏和# if RP_HOST宏包裹住on loading的主干部分,以免输出太多同质化信息让我眼花缭乱。

但是我发现,不管让这个主干代码在host中执行、还是在node中执行、还是在node0中执行,最后都会在加载过程中卡住不动。

于是我无奈只好更改为不使用编译器指令——诸如# if RP_HOST等宏。

猜你喜欢

转载自blog.csdn.net/PSpiritV/article/details/129940471