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/)
-   -   Parallel UDF Segmentation fault error (https://www.cfd-online.com/Forums/fluent-udf/181317-parallel-udf-segmentation-fault-error.html)

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 */
}


KevinZ09 January 9, 2017 05:30

I managed to get this UDF working a couple weeks ago. For any future references, the segmentation error was caused by making calls to interior faces, while they only work on boundary faces.

Also, to get a proper area-weighted average, the temperature needs to be multiplied by the area before summing and no need to use F_UDMI; can just define T_mean outside the macro so it's known outside the macro too.


All times are GMT -4. The time now is 01:10.