CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (https://www.cfd-online.com/Forums/fluent-udf/)
-   -   UDF bug, for reversing flow direction and magnitude (https://www.cfd-online.com/Forums/fluent-udf/226011-udf-bug-reversing-flow-direction-magnitude.html)

EngGhost April 14, 2020 16:24

UDF bug, for reversing flow direction and magnitude
 
Dear all,
Iím trying to write a UDF code for simulating reversed flow in a pipe, water is supposed to flow from the right to left with initial velocity (v_i=-0.13) for 1 second (t_forward=1), then the flow should be reversed and flow from left to right until it reaches a final velocity (v_f=0.05) and continue flowing with this velocity (v_f=0.05) till the end of the simulation, the deceleration that the flow will change its direction and magnitude with is (a=0.136).
I change the time step manually through the simulation (0.1 then 0.05 and 0.002), so I want it to be automatically loaded in the UDF by declaring
real t_step= CURRENT_TIME - PREVIOUS_TIME ;
And the full code I assigned to the boundary mass flow rate inlet is:
************************************************** *********
#include "udf.h"
#include "unsteady.h"
DEFINE_PROFILE(v_inlet0_136, t, i)
{
face_t f;
real t_step= CURRENT_TIME - PREVIOUS_TIME;
real v_i=-0.13;
real v_f=0.035;
real a=0.136;
real v =v_i;
real t_forward =1;
begin_f_loop(f, t)
{
if (CURRENT_TIME< t_forward)
{
v =v_i;
}
else
{
if (v >v_f)
{
v =v_f;
}
else
{
v =v +(a*t_step);
}
}
F_PROFILE(f,t,i) = v;
}
end_f_loop(f, t)
}
************************************************** *********
The problem after interpreting the UDF file and running the simulation is that:
After 1 second of forward flowing with v=v_i=0.13, the flow is not reversed, but only decreased by the value of (a*t_step=0.136*0.1=0.0135) as if the line of (v =v +(a*t_step) ; ) is executed for only one time and not looped until the value of v reaches v_f.
Iíve searched for a similar problem in the UDF manual but I couldnít find any,
Can anyone please help me to make the code working, and make the loop continues???Ö
Thanks a lot in advance.

vinerm April 15, 2020 03:58

Velocity Profile
 
If the time-step in your simulation is fixed, then you do not need this UDF. You can write it as a transient profile and hook the profile.

The bug in the code is defining v = v_i. Every time the code is executed, v is reset to v_i. Since everything else is constant, it will never reach v_f.

EngGhost April 15, 2020 10:11

Quote:

Originally Posted by vinerm (Post 765730)
The bug in the code is defining v = v_i. Every time the code is executed, v is reset to v_i. Since everything else is constant, it will never reach v_f.

thanks a lot for your reply, vinerm,

I've modified the code without assigning an initial value for v :

Code:

************************************************** *********
#include "udf.h"
#include "unsteady.h"
DEFINE_PROFILE(v_inlet0_136, t, i)
{
face_t f;
real t_step= CURRENT_TIME - PREVIOUS_TIME;
real v_i=-0.13;
real v_f=0.035;
real a=0.136;
real v ;
real t_forward =1;
begin_f_loop(f, t)
{
if (CURRENT_TIME< t_forward)
{
v =v_i;
}
else
{
if (v >v_f)
{
v =v_f;
}
else
{
v =v +(a*t_step);
}
}
F_PROFILE(f,t,i) = v;
}
end_f_loop(f, t)
}
************************************************** *********

but after the one second forward flow passes, the flow rate instantaneously reaches 0+(a*t_step)=0.0136!!
which means two things:
1st: the code didn't recognise the previous value of v and considered it as zero,
2nd: the loop didn't work, because the code only add the value of (a*t_step) once...
or maybe the loop worked but the value of (a*t_step) is being added each time to v=zero, so the value of v still constant and equals to zero+a*t_step.
.
.
.
I've tried to define:
real v;
inside the body of the loop and before the if statements but I got the the same output as if it calculate v=0 and doesn't increase its value.

EngGhost April 15, 2020 10:14

I wonder if there is a way to define the previous value of v of last time step and add the increment value of a*t_step to it without considering the value of v as zero in each new time step!?

vinerm April 15, 2020 10:25

static
 
Define it as static

EngGhost April 16, 2020 07:46

Quote:

Originally Posted by vinerm (Post 765798)
Define it as static

great thanks, Vinerm,
I've globally declared it outside the function and splitted the nested if statments and it finally worked 👍

EngGhost April 16, 2020 16:20

in case if someone wants to use the code :
Code:

#include "udf.h"

real v_now;

DEFINE_PROFILE(v_inlet, t, i)
{
face_t f;

real t_now= CURRENT_TIME;
real t_step= CURRENT_TIMESTEP;
real t_step2= CURRENT_TIME-PREVIOUS_TIME;

real v_initial= -0.13;
real v_final= 0.035;
real acc= 0.136;
real t_forward=0.5;


begin_f_loop(f, t)
{
        if ( t_now <= t_forward)
        {
                v_now = v_initial;
        }
        else
        {
                v_now = v_now + ( acc * t_step2 );
        }
        if (v_now > v_final)
                {
                        v_now = v_final;
                }
        F_PROFILE(f,t,i) = v_now;
        printf("%f", v_now);
}
end_f_loop(f, t)
}

but there's some bug in the code that is :
the loop is excuted every iteration and not every time step, which causes the flow to decelerate very very fast then the actual rate of the input deceleration (in 0.1s instead of 1.12s)
I hope there is some way to make the code loops once in the time step, because it loops 41 times per iteration and iterations are 20 per time step, i. e. the the deceleration is 41*20 times faster than the actual rate...
please help.

vinerm April 17, 2020 15:18

The bug
 
The code still has bug in it. Each time the code is executed, i.e., every iteration, v_now is reset. If you define it as static real v_now, then its value will be maintained even after the function ends. However, a better idea would be to create an rpvar. You can store the value in rpvar and call it when required and set it. This will ensure that v_now is not reset, ever, until and unless user wants it to.

EngGhost April 18, 2020 09:34

Quote:

Originally Posted by vinerm (Post 766205)
The code still has bug in it. Each time the code is executed, i.e., every iteration, v_now is reset. If you define it as static real v_now, then its value will be maintained even after the function ends.

thanks Vinerm for your following up,
actually I've tried to define the v_now as :
static real v_now;
but an error occured when I tried to intrpret the code "parse error".
.
.
but I want to clarify that the code worked well when I defined v_now globally out of the function, and its value is not being reset after each loop,
the only problem is that the loop is over the face cells (which are 41 cells of the face mesh) so the value of v_now increases 41 times per iteration and 20 times of iteration per time step,
I guess the bug is in the loop function that needs to be changed from looping over each cell in the face, to be over the whole face at once, and one time in the time step and not each iteration in the time step.
I hope I could explained the problem correctly,
and hope you can help me in changing the loop function/syntactic.
thank you..

vinerm April 18, 2020 10:30

Loop
 
Loop is required only for applying the profile. Do the calculation outside the loop, i.e., before begin_f_loop.

EngGhost April 18, 2020 13:00

Quote:

Originally Posted by vinerm (Post 766288)
Loop is required only for applying the profile. Do the calculation outside the loop, i.e., before begin_f_loop.

I've moved the if statments out of the loop and the loop contains only the profile update line:
F_PROFILE(f,t,i) = v_now;

but the :
v_now = v_now + ( acc * t_step2 );
is still updated over each 41 cell in the inlet face and the 20 iteration per time step,
.
.
but I've tried to manipulate the code be divided the acceleration (acc) by no. of cells in the inlet face multiplied by no. of iterations per time step, i. e. :
v_now = v_now + ( acc * t_step2 / (41*20));

and the results werebvery close to the actual reversing time (1.4 instead of 0.1 s)
but I have to count the mesh cells in the inlet face manually,
is there any code (or even an automatic way) to count the no. of cell in a selected face?
this will solve the problem I guess..
thanks for your patience and support dear Vinerm,

vinerm April 18, 2020 16:15

Count
 
You can setup a counter, set it to 0 outside begin_f_loop and then increase it by 1 within the loop. However, you will come to know about the total only in the end.

DEFINE_PROFILE can be made to execute after 10 or 20 iterations but you cannot change it at every time-step (you can but you don't want to). So, a better alternative is to break the code. Do the calculation inside a DEFINE_EXECUTE_AT_END. This macro is executed only at the end of the time-step; only once. And then use the calculation done by DEFINE_EXECUTE_AT_END inside DEFINE_PROFILE. Other option, as suggested earlier, is to use an rpvar.

EngGhost April 20, 2020 07:50

really great thanks dear Vinerm,
I've changed the loop to be over the thread and the profile update interval to be 20 as the max iteration per time step, anf the code seems to work fine,
I will examine it with small time step and if it works till the end without errors I will post it here so anyone can use it if needed..
thanks again Vinerm for your sincere help...


All times are GMT -4. The time now is 23:56.