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/)
-   -   Looping macro for DPM (https://www.cfd-online.com/Forums/fluent-udf/218723-looping-macro-dpm.html)

hjubaer July 1, 2019 23:08

Looping macro for DPM
 
Hi all,

I am aware that in the customization manual there are some examples of looping macros including one to loop over all particles in a cell. But I was just wondering if there is any way of defining a certain radius around let's say a cell, where the tracked particle is currently located, and then loop over all particles that are located within that defined radius? May be we can identify the cells that fall withing that radius and then extend our looping macro to go over multiple cells, instead of just one?

Thanks a lot for your help in advance.

With best regards
Hasan

AlexanderZ July 2, 2019 00:11

you may define cell by it's coordinates and find all adjusted cells within radius, which you specify

to make this loop over all cells and check if coordinates are inside sphere.

Ansys Fluetn Customization manual -> C_CENTROID

best regards

hjubaer July 2, 2019 21:39

Hi Alexander,

Thanks a lot for your very helpful hint. In order to confirm what you suggested, I have drafted a test code. Would you please check my test code and let me know whether or not I was able to implement the idea correctly.

The other idea I have is to check it with DEFINE_ON_DEMAND, however this UDF has no pointer to the tracked particle. Perhaps you have a hint to resolve that issue.
Furthermore, I was wondering if there was any alternative way of doing the check, as opposed to unnecessarily going through the entire domain. Because if I execute this every time step it is going to take forever, isn't it?

Cheers
Hasan

Code:

#include <udf.h>

DEFINE_DPM_SCALAR_UPDATE(count_cells, cell, thread, initialize, tp)
{
        real xc0[ND_ND];
        C_CENTROID(xc0, cell, thread); /*This should be my reference cell where
                                                                  the currently tracked particle is located*/

        Domain *d;
        d = Get_Domain(1); /*get the domain ID of fluid*/

        cell_t c;
        Thread *t;
        real xc[ND_ND];
        int counter = 0;
        int n = 0;
        /* loop over all cell threads in the domain */
        thread_loop_c(t, d)
        {

                /* loop over all cells */
                begin_c_loop_int_ext(c, t)
                {
                        C_CENTROID(xc, c, t);
                        if (sqrt(ND_SUM(pow(xc[0] - xc0[0], 2.),
                                pow(xc[1] - xc0[1], 2.),
                                pow(xc[2] - xc0[2], 2.))) < 0.1)
                                counter++;/*count if within radius of 10 cm*/
                        else
                                n++;/*count if not within radius*/
                }
                end_c_loop_int_ext(c, t)
        }

        /*this is to check the calculation, do not mind the formatting*/
        FILE *debugf;
        debugf = fopen("debugf_1.txt", "a");
        fprintf(debugf, "%d %d\n", n, counter);
        fclose(debugf);
}


AlexanderZ July 3, 2019 04:32

first of all, try to compile your code, you will get some errors.

I don't understand your line
Code:

C_CENTROID(xc0, cell, thread); /*This should be my reference cell where the currently tracked particle is located*/
C_CENTROID gives you coordinates of this cell
so you get them, but later do the same again
Code:

C_CENTROID(xc, c, t);
also, don't need loop over cell/thead, because it is already implemented in DEFINE_DPM_SCALAR_UPDATE macro

so delete:
Code:

thread_loop_c(t, d)
        {

                /* loop over all cells */
                begin_c_loop_int_ext(c, t)
                {
                        C_CENTROID(xc, c, t);

for this part you should specify coordinates xc0, which is your reference actually. So my idea is -> you define center of sphere (xc0) and radius, using C_CENTROID you check if the cell is inside sphere or not.
Code:

if (sqrt(ND_SUM(pow(xc[0] - xc0[0], 2.),
                                pow(xc[1] - xc0[1], 2.),
                                pow(xc[2] - xc0[2], 2.))) < 0.1)

last part may take the most executable time
Code:

FILE *debugf;
        debugf = fopen("debugf_1.txt", "a");
        fprintf(debugf, "%d %d\n", n, counter);
        fclose(debugf);

you may use C_UDMI(c,t,0) for that and write to file late using DEFINE_EXECUTE_AT_END macro (for instance)

to be
Code:

C_UDMI(c,t,0) = n;
C_UDMI(c,t,1) = counter;

and add
Code:

DEFINE_EXECUTE_AT_END(write_log)
{
Domain *d;
Thread *t;
cell_t c;
FILE *debugf;
d=Get_Domain(1);
debugf = fopen("debugf_1.txt", "a");
thread_loop_c(t,d)
{
begin_c_loop(c,t)
{
fprintf(debugf, "%d %d\n", C_UDMI(c,t,0), C_UDMI(c,t,1));
}
end_c_loop(c,t)
}
}
fclose(debugf);
}

something like this

best regards

hjubaer July 3, 2019 07:09

first of all, thanks heaps! You are awesome!!

Let me quickly explain the part that created confusion. My understanding was

Code:

C_CENTROID(xc0, cell, thread);
is extracting the coordinates of the centre of the cell, where the tracked particle is currently located. Please correct me if I am wrong. Perhaps I should take the easier alternative way and just go with
Code:

TP_POS(tp)[0], TP_POS(tp)[1], TP_POS(tp)[2]
instead. The centre of the sphere (point of reference) that you mention is actually for me the actual position of the tracked particle. Then through the thread and cell loop I was merely trying to check each and every cell in the domain (perhaps unnecessary?) by at first extracting their coordinates through
Code:

C_CENTROID(xc, c, t);
and then calculating the distance from the reference, in order to check against the criterion sqrt(delx^2+dely^2+delz^2)<0.1.
I know that I do not need to check all the cells in the domain, as most of them would obviously be outside the reach/radius. But Is there any way to limit my search to the neighbouring threads only?

Does it make sense now?

Cheers
Hasan

hjubaer July 5, 2019 23:45

Hello everyone,

Is there any way to loop through all the particles in my calculation domain (transient case) without going into the thread and cell loop?

Code:


Particle *p;
Injection *Ilist, *I;
Ilist = Get_dpm_injections();

loop(I, Ilist)
{
        loop(p, I->p_init) /* Standard ANSYS Fluent Looping Macro to get particle streams in an Injection */

        {/*do whatever calculation is needed in here*/
        }

}

Does this actually loop through all the particles in the calculation domain or it just look at the initial streams in the injections? I'd really appreciate some help.

Cheers
Hasan

AlexanderZ July 8, 2019 01:21

Code:

C_CENTROID(xc0, cell, thread);
returns coordinates of cell you are in (during cell/thread loop), so it's not what you want
Aa you've mentioned, you need
Code:

P_POS(tp)[0], P_POS(tp)[1], P_POS(tp)[2]
to get coordinates=, which are the center of the sphere (point of reference).

For more information about UDF for DPM read Ansys FLuent Customization manual , DPM Macros chapter

best regards

hjubaer July 8, 2019 22:18

Thank you for your time and help.


All times are GMT -4. The time now is 06:17.