Optimizing UDF Code
Dear all
We have written a code in udf of fluent,It works good, but very slow. First we used "interpreted" then "compiled" again it works slow. Does anybody know that what wrong is with it? Please write me your recomend. And if you can saw any documentation with optimizing fluent udf code help us. Meanwhile, what advantage is between coding in fluent,in comparison with other compilers? Thanks 
Re: Optimizing UDF Code
what is the function of your UDF? Does it include any file read and write? Or any UDF memory? How do you judge that your computing is very slow?

Re: Optimizing UDF Code
Thanks Kim
I have used only usual function. It dosn't read or write any file.In comparison to fortran code it is so slower. It response after about 5 hours but in fortran it response in 1 to 2 minutes. I have used four uds that in three of equations the time derivative is absent but in one of them I have time derivative. So, I supposed unsteady problem but in three of equations I added time derivative in right hand side.I had to use uds0 to uds3 and their function in all of my subroutines meanwhile the system of equations has nonlinear coefficient of uds0 to uds3. I used only 50*50 grid.after compiling I expected it works very fast but it didn't do.If you have general recommend please tell me. Sebeci 
Re: Optimizing UDF Code
You are right, with a 50x50 grid, your code should be really fast.
I had a similar problem solving a UDS. In my case, this was due to redundand loops over cells. Hi ap 
Re: Optimizing UDF Code
Sounds like your source terms may be causing a numerical stiffness that FLUENT doesn't like. Is the slownness the number of iterations to convergence or that each iteration itself is very slow??
If the former then probably the problem isn't setup right. If you've redefined the unsteady terms of the uds be careful with the numbers used in the su and apu parts of the term. You may find that smallnonzero numbers work better than zero and largish numebrs work better than infinite numbers (if you get what I mean). Greg 
Re: Optimizing UDF Code
Hi, Could you issue your source code if it is possible?

Re: Optimizing UDF Code
Well there's generally no point  since each code is for a specific problem and its often difficult to work out what other people do.
Do you know what's causing the slowness??? You would expect FLUENT to be slower than Fortran, but I reckon you may not have the source terms quite right. I've found this alot with my own codes. Have you read the UDF manual?? Feel free to ask me any specific questions. Greg 
Re: Optimizing UDF Code
Thanks All
My source code is in below. In my problem I have only a simple geometry as square.I implemented boundary conditions as no flux for uds0,uds1 and constant for uds2 and uds3 for all edges.As a matter of fact, I used one cell for applying BC of uds3 in the botton left cell and another in the up right cell as source term in code.I omited flow equations and I have setted fluent to solve only uds0 to uds3 equations. Meanwhile, I have taken answer after 8 minuts for 10*10 grid. #include "udf.h" #define K 0.008 #define Q1 0.5 #define Dp 0 #define INJS 1.0 #define INIS 0.2 /* solving equation1: u=kd(s2)*dp/dx by using source=u+kd(s2)dp/dx =0 I have taken u=s0 and p=s3 */ DEFINE_SOURCE(U, c, t, dS, eqn) { real physical_dt, vol, rho, phi_old,Sunsteady,a,b; real S2=C_UDSI(c,t,2); real S0=C_UDSI(c,t,0),S3x=C_UDSI_G(c,t,3)[0]; real dm=S2*S2+((1.0S2)*(1.0S2)); real SourceU= (S0)K*dm*(S3x); physical_dt = RP_Get_Real("physicaltimestep"); vol = C_VOLUME(c,t); rho = C_R_M1(c,t); a = rho*vol / physical_dt;/*implicit part*/ phi_old = C_STORAGE_R(c,t,SV_UDSI_M1(0)); b = rho*vol*phi_old/physical_dt;/*explicit part*/ dS[eqn]=(1.0+a); Sunsteady=a*C_UDSI(c,t,0)+b; return (SourceU+Sunsteady); } /* */ DEFINE_ADJUST(adj,d) { Thread *t,*f_thread; cell_t c; cell_t c0,c1; face_t f; real x,y,fs,f1,S2,dm; real xc[ND_ND]; thread_loop_c(t,d) { begin_c_loop(c,t) C_CENTROID(xc,c,t); y=xc[1]; x=xc[0]; if ((x>0.98)&&(y>0.98)) { C_UDSI(c,t,3)=Dp; } end_c_loop(c,t) } thread_loop_c(t,d) { begin_c_loop(c,t) C_CENTROID(xc,c,t); y=xc[1]; x=xc[0]; S2=C_UDSI(c,t,2); dm=S2*S2+((1.0S2)*(1.0S2)); fs=((S2*S2)/dm); if ((xc[0]<0.02)&&(xc[1]<0.02)) { C_U(c,t)=Q1; C_UDSI(c,t,2)=INJS; C_V(c,t)=(1.0fs)*Q1; } else if((xc[0]>0.98)&&(xc[1]>0.98)) { C_U(c,t)=Q1; } else { C_U(c,t)=0; } end_c_loop(c,t) } } /* */ /* solving equation2: v=kd(s2)*dp/dy by using source=v+kd(s2)dp/dy =0 I have taken v=s1 and p=s3 */ DEFINE_SOURCE(V, c, t, dS, eqn) { real physical_dt, vol, rho, phi_old,Sunsteady,a,b; real SourceV; real S2=C_UDSI(c,t,2); real S1=C_UDSI(c,t,1),S3y=C_UDSI_G(c,t,3)[1]; real dm=S2*S2+((1.0S2)*(1.0S2)); SourceV= (S1)K*dm*(S3y); physical_dt = RP_Get_Real("physicaltimestep"); vol = C_VOLUME(c,t); rho = C_R_M1(c,t); a =rho*vol / physical_dt;/*implicit part*/ phi_old = C_STORAGE_R(c,t,SV_UDSI_M1(1)); b =rho*vol*phi_old/physical_dt;/*explicit part*/ Sunsteady=a*C_UDSI(c,t,1)+b; dS[eqn]=(1.0+a); return (SourceV+Sunsteady); } /* */ /* solving du/dx+dv/dy=q1 where u=s0 and v=s1 */ DEFINE_SOURCE(Continuity, c, t, dS, eqn) { real physical_dt, vol, rho, phi_old,Sunsteady,a,b; real SourceCo; SourceCo=(C_UDSI_G(c,t,0)[0])(C_UDSI_G(c,t,1)[1])+C_U(c,t); physical_dt = RP_Get_Real("physicaltimestep"); vol = C_VOLUME(c,t); rho = C_R_M1(c,t); a =rho*vol / physical_dt;/*implicit part*/ phi_old = C_STORAGE_R(c,t,SV_UDSI_M1(3)); b =rho*vol*phi_old/physical_dt;/*explicit part*/ Sunsteady=a*C_UDSI(c,t,3)+b; dS[eqn]=(0+a); return (SourceCo+Sunsteady); } /* */ /*DEFINE_DIFFUSIVITY(diffusivity1, c, t, i) { if (i==0) { C_UDSI_DIFF(c,t,0)=0; return C_UDSI_DIFF(c,t,0); } else if(i==1) { C_UDSI_DIFF(c,t,1)=0.0000001; return C_UDSI_DIFF(c,t,1); } if (i==2) { C_UDSI_DIFF(c,t,2)=0; return C_UDSI_DIFF(c,t,0); } if (i==3) { C_UDSI_DIFF(c,t,3)=0; return C_UDSI_DIFF(c,t,0); } }*/ /* */ DEFINE_SOURCE(SourceS2,c ,t ,dS,eqn) { real physical_dt, vol, rho, phi_old,Sunsteady,a,b; real Sup, Sop, su, apu; real SourceTot,SourceA,SourceB,SourceC,SourceD; real fs,fps2,fzegs2; real dgamabeds2=0;/* gama is D(x,y) */ real d2gamabeds2=0; real S2=C_UDSI(c,t,2); real dm=S2*S2+((1.0S2)*(1.0S2)); fs=((S2*S2)/dm); fps2=(2.0*S2/dm)((4.0*S22.0)*S2*S2)/(dm*dm); fzegs2=(2.0/dm)((4.0*S22.0)*2.0*S2/(dm*dm))((4.0*S2*S2+ (2.0*S2*(4.0*S22.0)))*(dm*dm)(2.0*dm*(4.0*S22.0)*(4.0*S22.0)*S2*S2))/(dm*dm*dm*dm); SourceA=fps2*C_UDSI_G(c,t,2)[0]*C_UDSI(c,t,0); SourceB=fps2*C_UDSI_G(c,t,2)[1]*C_UDSI(c,t,1); SourceC=dgamabeds2*C_UDSI_G(c,t,2)[0]*C_UDSI_G(c,t,2)[0]; SourceD=dgamabeds2*C_UDSI_G(c,t,2)[1]*C_UDSI_G(c,t,2)[1]; SourceTot=(SourceA+SourceB+SourceC+SourceD+C_V(c,t )); dS[eqn]=((fzegs2*C_UDSI_G(c,t,2)[0]*C_UDSI(c,t,0)) (fzegs2*C_UDSI_G(c,t,2)[1]*C_UDSI(c,t,1)))+(C_UDSI_G(c,t,2)[0]*C_UDSI_G(c,t,2)[0]+C_UDSI_G(c,t,2)[1]*C_UDSI_G(c,t,2)[1])* (d2gamabeds2)fps2*0.5; return SourceTot; } /* */ DEFINE_INIT(ini,d) { cell_t c; Thread *t; real xc[ND_ND]; thread_loop_c(t,d) { begin_c_loop(c,t) { C_CENTROID(xc,c,t) if((xc[0]<0.02)&&(xc[1]<0.02)) { C_UDSI(c,t,2)=INJS; } else C_UDSI(c,t,2)=INIS; } end_c_loop_all(c,t) } } 
Re: Optimizing UDF Code
Hi
I had a very quick look at your code. I don't think you're handling the source terms for the transient terms correctly. You actually can't easily implement transient terms using a source term, since its not possible to do the implicit part correctly. This will be one reason for the slow convergence. Instead you should write a DEFINE_UNSTEADY udf to handle the implicit and explicit parts of the transient term. You will find this explained in the udf manual. Also I've never found the C_UDSI_G function to be correct when used within the code  I think its best to use only for postprocessing. Why? Well sicne this is a control volume code, you really should consider the conservation of fluxes over the volume  ie calculate the sum of the face flxues. In this case the gradient at each face is different and you can't just add a single gradient term as a volumetric source. The better but more tedious route is to manually calculate all the face flxues and add then up to get the volumetric source term. I've checked with my own code and I think this is the only way to properly handle the pde. Otherwise you will have numerical errors..... To calculate the face fluxes you need to apply the divergence theorem in general. Good Luck Greg 
Re: Optimizing UDF Code
Hi, I also check the code and think Greg's opinion is right. You should use C_UDSI_G very carfully. And FLUENT does not recommend use C_UDSI_G directly. Instead, reconstruction gradien(RG) may be better.Why?
"The gradients stored in variables with the _G suffix are nonlimited values and if used to reconstruct values within the cell (at faces, for example), may potentially result in values that are higher (or lower) than values in the surrounding cells. Therefore, if your UDF needs to compute face values from cell gradients, you should use the reconstruction gradient (RG) values instead of nonlimited gradient (G) values. Reconstruction gradient variables are identified by the suffix _RG, and use the limiting method that you have activated in your FLUENT model to limit the cell gradient values."FLUENT UDF manu 5.3. 
Re: Optimizing UDF Code
Good point Kim.
Is there a C_UDSI_RG  I haven't checked?? 
Re: Optimizing UDF Code
thanks friends
But, as you know, fluent permits to choose only "default" and "none" in unsteady function UDS.So I had to use unsteady term in my source terms for omitting time derivative from left hand side.(Because in my system of PDEs only one equation had time derivative) In addition I didn't exactly understand that how use of reconstruction gradiant can help to fastering my program. I will be grateful if you explain it to me more. 
Re: Optimizing UDF Code
As I said above you can use a udf for the transient term. read the udf manual to find out how  they do have an example.
Greg 
Re: Optimizing UDF Code
Dear Greg Perkin
If I can assign *apu and *su to zero I think it possible, but i don't know that how I can omit transient term from unsteady problem. Thanks 
Re: Optimizing UDF Code
I don't think you can use zero for the implicit part.

Re: Optimizing UDF Code
I am sure I can't.So haow can omit unsteady term withot using any derivative source term in right hand side.

Re: Optimizing UDF Code
You can't eliminate completely, but by making this term small in comparison to others it will have no effect.
So maybe use a very small number say 1.0e10 or 1.0e6 whatever. Then it will have no impact relative to the other terms. This is sort of the numerical equivalent of considering the magnitude of nondimensional terms and eliminating those that aren't significant. Greg 
Re: Optimizing UDF Code
Thnks I will try it. As another qustion in relate to that code I want to know that how I can share some variables(for example d(s)) to other subroutines,I think it may reduce cpu time.
Meanwhile I didn't understand that why using C_UDS_G can increase the cpu time. 
Re: Optimizing UDF Code
Hi all I tried it, and the solving speed incereased but not more than I expected.I want to know any other recommendation. Meanwhile, I repeat again my question "I want to know that how I can share some variables(for example d(s)) to other subroutines in Fluent"
thanks for any help Sebeci 
All times are GMT 4. The time now is 15:05. 