FLUENT V5 - How to retrieve and use solution values from multiple parallel partitions within a user-defined function (UDF)


This is a combined UDF and parallel question:

I use DEFINE_PROFILE to define the temperature at an inlet.
I use DEFINE_ADJUST to average the temperature over the domain. The result is saved to a global variable, whose value is used in the above DEFINE_PROFILE (temperature at inlet depends on the average temperature in the domain). Everything fine so far.

BUT: How do I do this in parallel?

The averaging must be done in each node, and the results must be collected and combined at one place. The result is then to be communicated to (at least) the node(s) whose partition(s) contain/s the inlet, for which the temperature is to be defined.

Another scenario is that not the domain average temperature influences the inlet temperature, but only the temperature at an outlet. In this case, the same question arises if inlet and oulet happen to lie in different partitions (or, even worse, they are distributed over several partitions each).
You need a summation of certain quantities over all partitions.
This is done with:
sum = PRF_GRSUM1(quant);
This function must be called in a UDF that is executed by all Nodes AND the Host, i.e. DEFINE_ON_DEMAND, but _not_ DEFINE_ADJUST and many others.
To have this executed once per iteration, use a command monitor: Solve---Monitor---Command, enter:
/define/user/uod "on_demand"


Sample UDF source:
----------------------------------

#include "udf.h"

#define ZONE_ID 13

#ifdef STRUCT_REF
#define PRINT printf
#else
#define PRINT CX_Message
#endif

real vol_summe = 0.;
real tmp_summe = 0.;

real tmp_avg = 293.0;

/*************************************************************/
/* Determine averaged Temperature in zone ZONE_ID */
/*************************************************************/

DEFINE_ADJUST(calc_avgs, domain)
{
Thread *the_zone;
cell_t c;

real cell_volu;
vol_summe = 0.;
tmp_summe = 0.;

the_zone = Lookup_Thread(domain, ZONE_ID);

begin_c_loop(c, the_zone)
{
cell_volu = C_VOLUME(c, the_zone);
vol_summe += cell_volu;
tmp_summe += cell_volu * C_T(c,the_zone);
}
end_c_loop(c, the_zone)
}

/*************************************************************/
/* set inlet temperature depending on "tmp_avg"... */
/*************************************************************/

DEFINE_PROFILE(inlet_temp_prof, thread, nvar)
{
face_t f;
float temp;

temp = tmp_avg * ... + ...;

begin_f_loop(f, thread)
{
F_PROFILE(f, thread, nvar) = temp;
}
end_f_loop(f, thread);
}

/* ======================================= */
/* Sum over all partitions...: */
/* ======================================= */

DEFINE_ON_DEMAND(on_demand)
{
PRINT("n");
PRINT("Node %d: vol_summe = %f, tmp_summe = %f.n",
myid, vol_summe, tmp_summe);

vol_summe = PRF_GRSUM1(vol_summe);
tmp_summe = PRF_GRSUM1(tmp_summe);

PRINT("Node %d: vol_summe = %f, tmp_summe = %f.n",
myid, vol_summe, tmp_summe);

#if !RP_HOST

if (SMALL > fabs(vol_summe))
{
PRINT("Node %d: vol_summe is too small here...n", myid);
}
else
{
tmp_avg = tmp_summe / vol_summe;
}

#endif /* !RP_HOST */

PRINT("Node %d: tmp_avg = %f.n",
myid, tmp_avg);
}
Note:
When Fluent runs in parallel, the macro "begin_c_loop" --- "end_c_loop" handles both all cells in the respective partition AND (usually) one layer of (so called "exterior") cells around the partition. Thus, if you want to do a summation over all cells, all these cells we be counted (at least) twice.
To avoid that, use "begin_c_loop_int" (and "end_c_loop_int") -- this macro (pair) will only access cells that are real part of the respective partition the compute node works on.





Show Form
No comments yet. Be the first to add a comment!