【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果

一、初始化对UDF运行的影响

初始化只会初始化网格上的物理数据、在UDF中常用的实际时间flow-time(CURRENT_TIME)、迭代步数N_ITER、UDM中的数据(其实也就是网格物理数据)。

初始化之后,UDF程序中的静态变量不会再初始化(程序变量初始化和fluent的初始化不同,请注意区分),也即fluent初始化后再计算不会让程序再回到第一次执行的状态,UDF程序依稀记得初始化前静态变量在运算过程中得到取值。

不知道各位读者理没理解上面这句话,如果不理解请再继续阅读下面的。

我举个例子。假设我们需要在UDF中实现写入数据,具体来说需要每次迭代结束时判断flow-time是否经历了一次写入周期(比如1秒写入一次),如果经历了一个周期就写入一次,而且第一次一定要写入一次。

为了实现上述特征,我编写了如下UDF代码。

DEFINE_EXECUTE_AT_END(iter_ending)
    {
        real End_iter_time=0.0;
        real curing_ratio_ave=0.0;  /* Volume weighted average curing degree */
        real heat_ave=0.0;  /* Volume weighted average heating energy */


        #if !RP_HOST
        Thread *sheet_ct;
        int sheet_id = sheet_zone_id;
        cell_t c;

        real curing_ratio_weighted_sum=0.0;
        real heat_weighted_sum=0.0;
        real volume_sum=0.0;
        #endif


        #if !RP_NODE
        FILE *fp = NULL;
        char filename[]="out.txt";
        static int remain_num = -1;  /* Static variables are initialized only once */
        #endif



        #if !RP_HOST
        sheet_ct = Lookup_Thread(Get_Domain(1), sheet_id);

        begin_c_loop_int(c, sheet_ct)
        {
            curing_ratio_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 0);
            heat_weighted_sum += C_VOLUME(c, sheet_ct) * C_UDMI(c, sheet_ct, 3);
            volume_sum += C_VOLUME(c, sheet_ct);
        }
        end_c_loop_int(c, sheet_ct)

        curing_ratio_weighted_sum = PRF_GRSUM1(curing_ratio_weighted_sum);
        heat_weighted_sum = PRF_GRSUM1(heat_weighted_sum);
        volume_sum = PRF_GRSUM1(volume_sum);
        curing_ratio_ave = curing_ratio_weighted_sum / volume_sum;
        heat_ave = heat_weighted_sum / volume_sum;
        End_iter_time = CURRENT_TIME;

        #endif

        node_to_host_real_4(End_iter_time, bou_temp, curing_ratio_ave, heat_ave);

        #if !RP_NODE
        if(N_ITER<1)  /* Clear the file when open the file for the first time */
        {
            if ((fp = fopen(filename, "w"))==NULL)
                Message("\nWarning: Unable to open %s for writing\n", filename);
            else
                Message("\nWriting info to %s...\n", filename);
                fprintf(fp, "real-time \t bou_temp \t  curing_ratio_ave \t heat_ave\n");
        }
        else
        {
            if ((fp = fopen(filename, "a"))==NULL)
                Message("\nWarning: Unable to open %s for writing\n", filename);
            else
                Message("\nIt is available to Write data to %s...\n", filename);
        }
        #endif

        #if !RP_NODE
        Message("real-time:%lf \t bou_temp:%lf \t  curing_ratio_ave:%lf \t heat_ave:%lf\n", End_iter_time, bou_temp, curing_ratio_ave, heat_ave);
        if(remain_num != (int) (End_iter_time / writig_frequency))
        {
            remain_num = (int) (End_iter_time / writig_frequency);
            Message("\nWritting data to %s...\n", filename);
            fprintf(fp, "%lf \t %lf \t %lf \t %lf \n", End_iter_time, bou_temp, curing_ratio_ave, heat_ave);
        }
        fclose(fp); 
        Message("Iter_Done\n");
        #endif
    }

我的UDF代码中的DEFINE_EXECUTE_AT_END宏里定义了一个静态变量。

静态变量有两个特点:1、不会被其他文件误调用,即使同名;2、取值仅仅初始化一次。

我就是看中了后面这一点,才在此处加了static关键字,因为我想让这个变量在程序在第一次执行时取值符合某种条件(满足条件就写入数据到文件),后续迭代步时取值仅仅由初始化代码的后面代码决定。

-------------------------------------UDF代码讲完了,接着讲常规操作-----------------------------------------

将刚定义好的cas文件载入,加载UDF后(在加载前编译成功,并且进行了hook和在边界条件等处应用了UDF),接着设置一个自认为合理的时间步长,开始计算。

可是,没一会儿就报错——浮点溢出了(floating point exception)。

于是乎我们进行一次fluent初始化,清除掉所有的网格数据(还有flow-time、N_ITER等),调小时间步长再计算(注意我们没有卸载UDF再重载)。

我们发现在UDF中的DEFINE_EXECUTE_AT_END宏里定义的初次运行会写入一次数字数据的操作(倒数第6行)失效了。

【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果_第1张图片
后来我猜测fluent初始化并不会让程序重新运行,让静态变量再一次进行(程序变量)初始化,因此flow-time必须满足个位更新(我在UDF源文件最前面的全局区域定义writig_frequency为1.0)的条件才会执行倒数第6行的代码。

这只是猜想,接下来我们在第二部分验证。

二、重载UDF再计算对UDF运行的影响

本部分研究【停止正在进行的计算后重载UDF再计算会产生的效果】。

如果你仅仅是用下图中的两个stop按钮之一停止计算,做一些步长调整(或其他参数调整)后,或者你停止计算后进行了初始化。

再重新开始计算时,你的程序之前保存的静态变量取值还保存着。

【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果_第2张图片

当我这次将原来加载的libudf卸载,重新加载时,再开始计算。

这次我发现,倒数第6行的代码被很快运行,说明这次程序满足第一次运行就写入数据的条件,也说明静态变量在重载后会被重新进行(程序变量)初始化。
【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果_第3张图片

三、后话

为了避免下一次再出现同样的问题,我在DEFINE_EXECUTE_AT_END宏中加了下面这条代码。

使得这个辅助判断的变量remain_num在第一次迭代时一定满足写入数据条件,不管是否之前已经执行过。【Fluent UDF】浮点溢出错误后初始化对UDF运行的影响、停止正在进行的计算后重载UDF再计算会产生的效果_第4张图片

你可能感兴趣的:(fluent,fluent,udf,fluent,UDF)