|
|
发表于 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:
#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;
#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;
#else
Message0("Warning: Function calc_residual() Not implemented in Parallel\n");
#endif
return resid;
}
|
|