Fluids

Fluids

Topics related to Fluent, CFX, Turbogrid and more.

How to find a cell if the coordinate of of the cell is given? (ANSYS FLUENT)

    • rakibul.buet19
      Subscriber

      Objective

      I am working on modeling ray-tracing using User-Defined Functions (UDF) in ANSYS Fluent as part of a laser welding simulation. The ray should reflect based on local surface orientation and deposit energy accordingly.


      Primary Question

      I need help understanding:

      a. How to perform a local cell search?

      I understand that DEFINE_SOURCE executes for all cells in the domain.
      However, in my case, I need to perform a cell-by-cell ray propagation, which effectively requires a nested cell loop:

      • For each cell, I want to trace a ray forward in a given direction.

      • The ray should traverse through neighboring cells until it hits an interface.

      b. Where should this logic be implemented?

      Should this ray-tracing and cell search logic be placed inside:

      • DEFINE_SOURCE,

      • or DEFINE_ADJUST?


      Context and Current Approach

      My current ray-tracing idea follows this step-by-step logic:

      1. Initialize Laser Direction

        • A laser direction vector is defined at the start (e.g., vertical downward or at an angle).

      2. Ray Hits the Interface

        • When the ray intersects with a cell interface (VOF-based), I:

          • Extract the coordinates of that interaction using C_CENTROID(c, t)

          • Compute energy absorption based on Fresnel equations and the angle of incidence

          • Calculate the reflected direction vector of the laser based on surface normal

      3. Next Steps (Where I'm Stuck)

        After computing the reflection vector, I want to continue tracing the ray. For that, I need to:

        • Perform a Cell Search Along a Vector

          • Starting from the current cell, march one cell at a time in the reflected direction

          • At each step, determine if the new cell contains an interface (e.g., using VOF check)

        • Coordinate-Based Cell Identification

          • The reflected ray may not pass through the centroid of the next cell

          • I will have a point in space (coordinate) along the ray direction

          • I need to determine which cell this coordinate belongs to

          • Then assess whether that cell has an interface


      Summary of What I Need Help With

      • Is it feasible (and efficient) to perform coordinate-to-cell mapping within Fluent UDFs?

      • How to loop through neighboring cells or search forward along a vector?

      • Should this be inside DEFINE_SOURCE, DEFINE_ADJUST, or a custom DEFINE_ON_DEMAND function or something else?

       

       

       

      Here is my current state of the UDF (the relevant portions) , I don't have any multiple reflection incorporated YET, I know how to calculate surface normals and stuff like that. : 

      DEFINE_ADJUST(adjust_gradient_heat, domain)
       {
           cell_t c;
           Thread *t;
           real grad_x, grad_y, grad_z, mag_grad;
           real alpha, liquid_frac;
       
           /* Loop over all cell threads in the domain */
           thread_loop_c(t, domain)
           {
               /* Loop over all cells in the thread */
               begin_c_loop_all(c, t)
               {
                   /* Access volume fraction alpha in cell c */
                   alpha = C_VOF(c, t);
       
                   /* Calculate gradient of volume fraction (VoF) in each direction */
                   grad_x = C_VOF_SURF_AREA_X(c, t);
                   grad_y = C_VOF_SURF_AREA_Y(c, t);
                   grad_z = C_VOF_SURF_AREA_Z(c, t);
       
                   /* Calculate magnitude of gradient */
                   mag_grad = sqrt(grad_x * grad_x + grad_y * grad_y + grad_z * grad_z);
       
                   /* Save magnitude in user memory for later use */
                   C_VMAG(c, t) = mag_grad;
       
                   /* Normalize the gradient vector to get unit normal if magnitude is sufficient */
                   if (mag_grad > small_num)
                   {
                       C_VOF_NX(c, t) = grad_x / mag_grad;
                       C_VOF_NY(c, t) = grad_y / mag_grad;
                       C_VOF_NZ(c, t) = grad_z / mag_grad;
                   }
                   else
                   {
                       /* If magnitude too small, set unit normal components to zero */
                       C_VOF_NX(c, t) = 0.0;
                       C_VOF_NY(c, t) = 0.0;
                       C_VOF_NZ(c, t) = 0.0;
                   }
       
                   /*
                    * Compute liquid fraction as a smooth step function:
                    * Liquid fraction = clamp( (α - (1 - Z_TAO)) / Z_TAO , 0, 1 )
                    * This smoothly transitions liquid fraction from 0 to 1 over thickness Z_TAO near interface.
                    */
                   liquid_frac = (alpha - (1.0 - Z_TAO)) / Z_TAO;
       
                   /* Clamp liquid fraction between 0 and 1 */
                   if (liquid_frac < 0.0)
                       liquid_frac = 0.0;
                   else if (liquid_frac > 1.0)
                       liquid_frac = 1.0;
       
                   /* Save liquid fraction in user memory */
                   C_LIQUID_FRAC(c, t) = liquid_frac;
       
               }
               end_c_loop_all(c, t)
           }
       }
       
       
      DEFINE_SOURCE(heat_source, c, t, dS, eqn)
      {
          real x[ND_ND];
          real time = CURRENT_TIME;
          real cell_z, cell_x;
          real T = C_T(c, t);

          /* Cell centroid coordinates */
          C_CENTROID(x, c, t);
          cell_x = x[0];
          cell_z = x[2];

          /* Radial distance from laser center moving in x-direction */
          real r = sqrt(pow(cell_x - x0 - v * time, 2.0) + pow(x[1] - y0, 2.0));

          /* Axial-dependent beam radius */
          real R_local = r0 * sqrt(1.0 + pow((cell_z - z0) / zr, 2.0));

          /* Phase threads: gas and solid */
          Thread *pri_th = THREAD_SUB_THREAD(t, 0);
          Thread *sec_th = THREAD_SUB_THREAD(t, 1);

          /* Mixture and phase densities and specific heats */
          real rho = C_R(c, t);
          real Cp = C_CP(c, t);

          real rhom = C_R(c, sec_th);
          real Cpm = C_CP(c, sec_th);

          real rhog = C_R(c, pri_th);
          real Cpg = C_CP(c, pri_th);

          /* Factor blending mixture properties for heat source */
          real factor = (2.0 * rho * Cp) / (rhom * Cpm + rhog * Cpg);

          /* Super-Gaussian order (flatness of beam) */
          int n_num = 2;

          real source = 0.0;

          /*
           * Apply heat source only in solid phase or near interface region
           * (VOF between 0.05 and 0.95)
           */
          if (cell_z <= Z_TOTAL || (C_VOF(c, sec_th) > 0.05 && C_VOF(c, sec_th) < 0.95))
          {
              source = ((2.0 * A * P * AMP_FACTOR) / (Pi * R_local * R_local))
                      * exp(-3.0 * pow(r / R_local, n_num))
                      * C_VMAG(c, t)
                      * factor;

              dS[eqn] = 0.0;  // Derivative of source term wrt temperature is zero
          }
          else
          {
              source = 0.0;
              dS[eqn] = 0.0;
          }

          return source;
      }

       

    • Rob
      Forum Moderator

      Staff can't go into too much detail, and I'm not debugging code.  Part of your problem is that the free surface isn't a facet or surface in Fluent, it's just a different material in the cell, so finding a normal may be more complicated. However, is the cavity full of molten liquid or are you vaporising the "solid"? 

    • rakibul.buet19
      Subscriber

      Thank you for replying. You don't have to debug any code. I just put it there for context. No, I haven't included any evaporative mass transfer mechanism. It's just a two phase VOF simulation, Air and metal phase (can be solid or liquid depending on liquid fraction value)

      All I want to know is, suppose I am at coordinate 0,0,0. I wannt to know that, a point A (x, y, z) , which cell this point might belong to? How do I find it? Is there any way like I can give fluent a coordinate and fluent will give me a cell id along with that cells centroid coordinate? 

      Here is an example of my model

       

    • rakibul.buet19
      Subscriber

      Let me make the question more clear: 

      Suppose I am at Point A, I know the distance d. I want to know the cell-centroid of the cell at Point B. 

      So what I am asking is, can i do a sequential search of neighboring cells one by one and approach point B gradually? is there any way to do that? 

      Looking forward to your reply Rob! 

      Here is an illustration : 

       

    • Rob
      Forum Moderator

      There will be, but I know from others who have done this that's it's not standard code. You can search around neighbouring cells: cell A has bounding facets, and you find the cell on the other side of that facet, then move on from there. It won't be efficient, and there is likely a better way of doing this. 

    • rakibul.buet19
      Subscriber

       

      I think you’re talking about this one right? Adjacent Cell Index ( F_C0, F_C1):   Rob - link removed, use the one I posted. 

       

       

       

    • Rob
      Forum Moderator

      Yes, but use the proper documentation and not the ancient copy that's floating around   https://ansyshelp.ansys.com/public/account/secured?returnurl=/Views/Secured/prod_page.html?pn=Fluent&pid=Fluent&lang=en  Macro's and the like do occasionally change. 

Viewing 6 reply threads
  • You must be logged in to reply to this topic.