TAGGED: fluent, ray-tracing-using-ansys, udf, vof
-
-
July 3, 2025 at 10:30 am
rakibul.buet19
SubscriberObjective
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:
Initialize Laser Direction
A laser direction vector is defined at the start (e.g., vertical downward or at an angle).
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
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 customDEFINE_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;}Â
-
July 3, 2025 at 1:52 pm
Rob
Forum ModeratorStaff 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"?Â
-
July 3, 2025 at 1:56 pm
rakibul.buet19
SubscriberThank 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
Â
-
July 3, 2025 at 2:09 pm
rakibul.buet19
SubscriberLet 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 :Â
Â
-
July 4, 2025 at 9:29 am
Rob
Forum ModeratorThere 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.Â
-
July 4, 2025 at 9:32 am
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.Â
Â
Â
Â
-
July 4, 2025 at 9:49 am
Rob
Forum ModeratorYes, 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.Â
-
- You must be logged in to reply to this topic.
-
3407
-
1057
-
1051
-
896
-
877
© 2025 Copyright ANSYS, Inc. All rights reserved.