KevinZ09 |
December 12, 2016 09:36 |
Parallel UDF Segmentation fault error
Hello all,
I could really use some help debugging the following UDF. It's a UDF that calculates the average temperature on one face, stores it and then gets used later on to set the backflow temperature of another face. I am able to compile it, both serial and parallel, but it's giving me segmentation faults when trying to run it. It seems like the parts where communication between nodes/host-and-node is occuring is causing problems, as it runs allright up till the part where it calls the PRF_GRSUM1 macros.
Most of the part of the code is similar to the Parallel UDF example of the UDF manual. If anyone has any clue as to what causes the segmentation fault, please let me know.
FYI: I compile it, then hook the ADJUST macro, and also allocate memory. Anything else I could be forgetting to do?
Thanks in advance,
Kevin
Code:
#include "udf.h"
#include "prf.h"
DEFINE_ADJUST(adjust, domain)
{
/* Variables used by serial, host, node versions */
int ID = 154; /* inlet ID of Expansion Vessel displayed in Fluent boundary conditions panel */
int ID_out = 153; /* outlet ID displayed in Fluent boundary conditions panel */
real total_area = 0.0;
real T_tot = 0.0;
real T_mean = 683.15; /* defined outside because will be used in multiple DEFINE macros */
real w;
real T_tot2;
real total_area2;
/* "Parallelized" Sections */
#if !RP_HOST /* Compile this section for computing processes only (serial
and node) since these variables are not available on the host */
Thread *thread;
Thread *thread_outlet;
face_t f;
real area[ND_ND]; /* area-vector, ND_ND = 2 for 2D and 3 for 3D calculations */
thread = Lookup_Thread(domain, ID); /* retrieve pointer to thread associated with outflow boundary */
thread_outlet = Lookup_Thread(domain, ID_out); /* retrieve pointer to thread associated with outflow boundary */
/* #if RP_NODE
Message("\nNode %d is calculating on thread # %d\n",myid, ID);
#endif RP_NODE */
begin_f_loop(f, thread) /* loop over all faces in thread "thread" */
{
/* If this is the node to which face "officially" belongs,*/
/* get the area vector and temperature and increment */
/* the total area and total temperature values for this node */
if (PRINCIPAL_FACE_P(f,thread)) /* Always TRUE in serial version */
{
w = F_W(f, thread); /* z velocity */
if (w >= 0.0) /* if fluid is going out... */
{
F_AREA(area,f,thread); /* returns real face area vector */
total_area += NV_MAG(area); /* NV_MAG computes magnitude of vector */
T_tot += F_T(f, thread); /* temperature of face f on thread thread */
}
}
}
end_f_loop(f, thread)
/*
Message("Total area before summing %f from node %d\n",total_area, myid);
Message("Total temperature before summing %f from node %d\n",T_tot, myid);
*/
#if RP_NODE
/* Perform node synchronized actions here. Does nothing in Serial */
total_area = PRF_GRSUM1(total_area);
T_tot = PRF_GRSUM1(T_tot);
#endif /* RP_NODE */
#endif /* !RP_HOST */
/* Pass the node’s total area and temperature to the Host for averaging */
node_to_host_real_2(total_area,T_tot); /* Does nothing in SERIAL */
#if !RP_NODE /* SERIAL or HOST */
/* Message("Total Area After Summing: %f (m2)\n",total_area); */
/* Message("Total Temperature After Summing %f (N)\n",T_tot); */
T_mean = T_tot/total_area;
/* Message("Average temperature on Surface %d is %f [K]\n",
ID, T_mean); */
#endif /* !RP_NODE */
/* Pass the calculated average temperature to all nodes for later use */
host_to_node_real_1(T_mean); /* Does nothing in serial */
#if !RP_HOST
begin_f_loop(f, thread_outlet)
{
F_UDMI(f, thread_outlet, 0) = T_mean;
}
end_f_loop(f, thread_outlet)
#endif /* !RP_HOST */
}
DEFINE_PROFILE(T_backflow, thread, position)
{
/* "Parallelized" Sections */
#if !RP_HOST /* Compile this section for computing processes only (serial
and node) since these variables are not available on the host */
face_t f;
begin_f_loop(f, thread)
{
/* F_PROFILE(f, thread, position) = T_mean; */
F_PROFILE(f, thread, position) = F_UDMI(f, thread, 0);
}
end_f_loop(f, thread)
#endif /* !RP_HOST */
}
|