找回密码
 注册
查看: 2749|回复: 3

两个UDF难题,大家帮忙出出主意

[复制链接]
发表于 2008-4-30 09:51:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
1. udf程序控制fluent操纵界面
问题描述:在fluent迭代计算过程中,courant num对迭代收敛非常重要,一般在初始计算时,courant num设置很小,当初场稳定后,courant num可以设置大一些,但需要人为的点击设置。
拟方案:是否可以编写udf在一定的迭代步数时,自动修改courant num数?如何实现?可能需要调用scheme语句,如何在udf中调用?
2. udf获取残差大小
问题描述:udf中没有专门的宏可以获取残差,但在有些场合需要判断迭代是否已经收敛,进而进行下一步的计算或调整。
拟方案:是否可以获取残差图的指针或句柄,通过分析残差图得到当前的残差大小?
大家多发表一下意见,出出主意,多多讨论,顶起来
发表于 2008-4-30 10:09:13 | 显示全部楼层

两个UDF难题,大家帮忙出出主意

fluent没有残差图吗?好像还有残差的数据文件吧。还有一点不太明白,通过分析残差来判断是否收敛好像不太好吧。
 楼主| 发表于 2008-4-30 16:17:08 | 显示全部楼层

两个UDF难题,大家帮忙出出主意

“fluent没有残差图吗?好像还有残差的数据文件吧。”
有残差图,想要实时的获得残差值,数据文件只能显示或write某一个残差。
“还有一点不太明白,通过分析残差来判断是否收敛好像不太好吧。”
这个不是关键问题
发表于 2008-5-10 00:03:27 | 显示全部楼层

两个UDF难题,大家帮忙出出主意

[这个贴子最后由kevinxiao在 2008/05/10 00:08am 第 1 次编辑]

Solutions:
Q1: basically there are two approaches for question No. 1
=====================================================
Approach1:  using a scheme file, a sample scheme is as following
;; Read case and data file
rcd *.cas.gz
;; Set timing and iterate NUM_ITER times
parallel/timer/reset
/solve/set/courant-number 1    ;; set your initial courant number
/solve/set/diss/amg-c 0          ;;  first order of discretization.
/solve/iterate 200               ;; iterations
;;
/solve/set/courant-number 5    ;; change courant number to 5
/solve/set/diss/amg-c 1          ;;  change discretization to second order
/solve/iterate 200               ;; another 200 iterations
;; above procedure can be iteratively continued
;; following codes are for unsteady modeling, may change it accordingly.
;;/solve/set/time-step 2.5e-6
;;/solve/dual-time-iterate 240 20
parallel/timer/print
;;
;; Write case and data
wcd *.cas.gz
y       ;; overwrite previous files
exit y          ;; exit, yes
Approach 2: revise the courant number in your UDF directly.
I only have experience to change the underrelaxation factor (UR). You should be able to perform it in a similar way though. Firstly, you need find the macro for courant number, then substitue into the following codes accrodingly.
Two examples below: one for temperature UR change, one for UDS.
static int MY_COUNTER = 1;        /* iteration monitor */
if (MY_COUNTER <= 100)      
      Domainvar_Set_Real(ROOT_DOMAIN_ID,"temperature/relax", 0.9);
else Domainvar_Set_Real(ROOT_DOMAIN_ID,"temperature/relax", 0.99);
float uds_urf[1];        /* define a variable for uds, change the number based on your uds ammounts */
if (MY_COUNTER <= 50) uds_urf[0] = 0.1;
else if (MY_COUNTER <= 100) uds_urf[0] = 0.5;
else  uds_urf[0] = 0.9;
Domainvar_Set_List_of_Float(ROOT_DOMAIN_ID, "uds/relax", uds_urf, 1);
Note that, above code work only in serial solver, i met troubles when run it in parallel. Let me know if anybody can fix this issue.
=================================================================
Q2. I got the solution for your second quesiotn from Fluent';s support database. Never try it yet, so cannot gurantee it works.
Problem:
Client wants to calculate solution residuals in a UDF so as to control solver settings.
The following UDF will do this.

Resolution:
&#35;include "udf.h"
real calc_residual(Domain* d, Var_Attribute *sv, int n, real scale, char* eqname);
DEFINE_ON_DEMAND(residuals)
{
Domain* d = Get_Domain(1);
cxboolean scale = TRUE;
real residual;
Var_Attribute *sv;
int i;
int n = nres - 1;
char eqname[128];
Message("\nResiduals\n===============================================\n");
/* Loop over all equation variables */
for(i=SV_MAX-1, sv=sv_master; i>=0; i--, sv++)
{
residual = calc_residual(d, sv, n, scale, eqname);
if (residual > 0) Message("%16s: %13.6e\n", eqname, residual);
}
}

real calc_residual(Domain* d, Var_Attribute *sv, int n, real scale, char* eqname)
{
real resid = 0.0;
&#35;if !PARALLEL
real sf;
int eqn_index;
eqn_index = NULLP(SV_METHOD(sv,residual_p)) ? EQ_NULL : SV_METHOD(sv,residual_p)(d,sv,RESIDUAL_INDEX);
/* This will be tru if equation is being solved */
if ((eqn_index != EQ_NULL) && (SV_METHOD(sv,residual_p)(d,sv,RESIDUAL_DISPLAY)))
{
if (n>0)
{
resid = DOMAIN_RES(d, eqn_index)[n];
strcpy(eqname, DOMAIN_EQN_LABEL(d, eqn_index));
if (scale)
{
sf = DOMAIN_RES_SCALE(d, eqn_index)[n];
if (sf > 0) resid /= sf;
}
}
else
resid = 1.0;
}
else
resid = 0.0;
&#35;else
Message0("Warning: Function calc_residual() Not implemented in Parallel\n");
&#35;endif
return resid;
}


您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表