We have an exciting announcement about badges coming in May 2025. Until then, we will temporarily stop issuing new badges for course completions and certifications. However, all completions will be recorded and fulfilled after May 2025.
Fluids

Fluids

Topics related to Fluent, CFX, Turbogrid and more.

Laser Melting heat source UDF issue [FLUENT Crashing]

    • Kanak BUET19
      Subscriber

      Hello everyone,

      I am trying to simulate Selective Laser Melting in Ansys Fluent. Its a two phase problem. So I am using VOF model.

      my domain dimension is :

      L = 0.8 mm (X axis)
      W = 0.2 mm (Y axis)
      H = 0.28 mm (Z axis)

      In this domain , I patched the domain ( x = 0.8 mm, y = 0.2 mm , z= 0.2 mm) as solid and the rest is gas.

      I am trying to model the heat source as surface heat source and place it at x = 0 mm , y = 0.1 mm and z is undefined as I will use if statement to find the interface ( where 0
      My UDF code is given below. After Compiling and initialising , when I try to view the user defined volumetric heat source under the contour tab , FLUENT Crashes instantly. I am not sure what went wrong. Yes I also created 5 user defined memory locations. Can anyone help?

      #include "udf.h"
      #include "sg_mphase.h"
      #include "mem.h"
      #include "sg_mem.h"
      #include "math.h"
      #include "flow.h"
      #include "unsteady.h"
      #include "metric.h"

      // Constants
      #define A 0.4 // Absorption coefficient
      #define P 200 // Laser power (W)
      #define R 40e-6 // Spot radius (m)
      #define v 0.5 // Scan speed of laser (m/s)
      #define Pi 3.1415926535 // Pi constant
      #define x0 0.0 // Initial x position of the laser (m)
      #define y0 0.1e-3 // Initial y position of the laser (m)

      // UDF for adjusting the gradient heat
      DEFINE_ADJUST(adjust_gradient_heat, domain)
      {
      Thread *t;
      Thread **pt;
      cell_t c;
      int phase_domain_index = 3.0; // thjats my metal domain
      Domain *pDomain = DOMAIN_SUB_DOMAIN(domain, phase_domain_index);

      Alloc_Storage_Vars(pDomain, SV_VOF_RG, SV_VOF_G, SV_NULL);
      Scalar_Reconstruction(pDomain, SV_VOF, -1, SV_VOF_RG, NULL);
      Scalar_Derivatives(pDomain, SV_VOF, -1, SV_VOF_G, SV_VOF_RG, Vof_Deriv_Accumulate);

      mp_thread_loop_c(t, domain, pt)
      if (FLUID_THREAD_P(t))
      {
      Thread *ppt = pt[phase_domain_index];

      begin_c_loop(c, t)
      {
      C_UDMI(c, t, 0) = C_VOF_G(c, ppt)[0];
      C_UDMI(c, t, 1) = C_VOF_G(c, ppt)[1];
      C_UDMI(c, t, 2) = C_VOF_G(c, ppt)[2];
      C_UDMI(c, t, 3) = sqrt(C_UDMI(c, t, 0) * C_UDMI(c, t, 0) +
      C_UDMI(c, t, 1) * C_UDMI(c, t, 1) +
      C_UDMI(c, t, 2) * C_UDMI(c, t, 2)); // Magnitude of gradient of volume fraction

      }
      end_c_loop(c, t)
      }

      Free_Storage_Vars(pDomain, SV_VOF_RG, SV_VOF_G, SV_NULL);
      }

      // UDF for defining the heat source
      DEFINE_SOURCE(heat_source, c, t, dS, eqn)
      {
      Thread *pri_th; // Gas phase
      Thread *sec_th; // solid phase
      real source;
      real x[ND_ND], time;
      time = CURRENT_TIME; // Acquire time from Fluent solver
      C_CENTROID(x, c, t); // Acquire the cell centroid location
      real T = C_T(c, t);

      pri_th = THREAD_SUB_THREAD(t, 0);
      sec_th = THREAD_SUB_THREAD(t, 1);





      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);
      real factor = (2 * rho * Cp) / (rhom * Cpm + rhog * Cpg);

      real r = sqrt(pow(x[0] - x0 - v * time, 2.0) + pow(x[1] - y0, 2.0));

      if (C_VOF(c, t) > 0.05 && C_VOF(c, t) < 1)
      {
      source = ((2 * A * P) / (Pi * R * R)) * exp((-2 * (r * r)) / (R * R))*factor * C_UDMI(c,t,3);
      dS[eqn] = 0.0;
      }
      else
      {
      source = 0.0;
      dS[eqn] = 0.0;
      }

      return source;
      }

    • Rob
      Forum Moderator

      What if a gradient is negative? 

    • Kanak BUET19
      Subscriber

      Even if the gradient is negative , I am squaring and rooting the x,y,z gradients and adding them in UDMI 3 right? It aint supposed to be the issue. However when I tried writing the heat source using DEFINE_PROFILE and used begin_f_loop , it worked (although I couldnt add any multiplying factor and gradient UDMI) . I need to multiply the "factor" and "UDMI" in order to convert the surface heat source to volumetric heat source.

       

      CODE : ( This heats up both my gasesous and solid phase , which I dont want)

       

      #include "udf.h"

      DEFINE_PROFILE(heat_source_profile, thread, position)
      {
          real x[ND_ND];
          face_t f;
          real current_time;
          real Q = 120; // Define your heat source magnitude (Watts)
          real rx = 5.3e-5; // Define your desired values for rx, ry, rz (meters)
          real ry = 250e-6;
          real rz = 5.3e-5;
          real A;
          real vel = 0.1e-3; // velocity @ m/s
          real PI = 3.1416;
          real x_pos;
          real x_start = 0; // Set your desired starting position in x (m)
          real y_start = 0.2e-3; // Set your desired starting position in y (m)
          real z_start = 0.1e-3; // Set your desired starting position in z (m)

       
         
          real x_local, y_local, z_local; // Declare local coordinates


       

         
          current_time = CURRENT_TIME;
          A = (6 * sqrt(3) * Q) / (PI * sqrt(PI) * rx * ry * rz);

          x_local = 0.0; // Initialize x_local outside the loop
          y_local = 0.0; // Initialize y_local outside the loop
          z_local = 0.0; // Initialize z_local outside the loop
         
          begin_f_loop(f, thread)
          {
              F_CENTROID(x, f, thread);
             
              // Transform global coordinates to local coordinates
              x_local = x[0] - x_start;
              y_local = x[1] - y_start;
              z_local = x[2] - z_start;
             
              x_pos = vel * current_time;

           
             
             
              // Compute the heat source function value
             
               F_PROFILE(f, thread, position) = A * exp(-3 * (pow(x_local - x_pos, 2.) / pow(rx, 2.) + pow(y_local, 2.) / pow(ry, 2.) + pow(z_local, 2.) / pow(rz, 2.)));
               
               
          }
          end_f_loop(f, thread)
      }
    • Rob
      Forum Moderator

      How would a face loop work on a VOF free surface?

    • Kanak BUET19
      Subscriber

       

      I have no idea sir :)) But I have worked something out :

      I have run the code ( added below) and the heat source part perfectly worked out ( i.e its being applied to where 0

      Code : 

       

      #include “udf.h”
      #include “sg_mphase.h”
      #include “mem.h”
      #include “sg_mem.h”
      #include “math.h”
      #include “flow.h”
      #include “unsteady.h”
      #include “metric.h”

      // Constants
      #define A 0.4 // Absorption coefficient
      #define P 200 // Laser power (W)
      #define R 40e-6 // Spot radius (m)
      #define v 0.5 // Scan speed of laser (m/s)
      #define Pi 3.1415926535 // Pi constant
      #define x0 0.2e-3 // Initial x position of the laser (m)
      #define y0 0.1e-3 // Initial y position of the laser (m)

      #include “udf.h”
      #include “sg_mphase.h”
      #include “mem.h”
      #include “sg_mem.h”
      #include “math.h”
      #include “flow.h”
      #include “unsteady.h”
      #include “metric.h”

      // UDF for adjusting the gradient heat
      DEFINE_ADJUST(adjust_gradient_heat, domain)
      {
      Thread *t;
      Thread **pt;
      cell_t c;
      int phase_domain_index = 3.0; // thjats my metal domain
      Domain *pDomain = DOMAIN_SUB_DOMAIN(domain, phase_domain_index);

      Alloc_Storage_Vars(pDomain, SV_VOF_RG, SV_VOF_G, SV_NULL);
      Scalar_Reconstruction(pDomain, SV_VOF, -1, SV_VOF_RG, NULL);
      Scalar_Derivatives(pDomain, SV_VOF, -1, SV_VOF_G, SV_VOF_RG, Vof_Deriv_Accumulate);

      mp_thread_loop_c(t, domain, pt)
      if (FLUID_THREAD_P(t))
      {
          Thread *ppt = pt[phase_domain_index];

          begin_c_loop(c, t)
          {
          C_UDMI(c, t, 0) = C_VOF_G(c, ppt)[0];
          C_UDMI(c, t, 1) = C_VOF_G(c, ppt)[1];
          C_UDMI(c, t, 2) = C_VOF_G(c, ppt)[2];
          C_UDMI(c, t, 3) = sqrt(C_UDMI(c, t, 0) * C_UDMI(c, t, 0) + C_UDMI(c, t, 1) * C_UDMI(c, t, 1) + C_UDMI(c, t, 2) * C_UDMI(c, t, 2)); // Magnitude of gradient of volume fraction



          }
          end_c_loop(c, t)
          }

          Free_Storage_Vars(pDomain, SV_VOF_RG, SV_VOF_G, SV_NULL);
      }


      // UDF for defining the heat source
      DEFINE_SOURCE(heat_source, c, t, dS, eqn)
      {
      Thread *pri_th; // Gas phase
      Thread *sec_th; // solid phase
      real source = 0.0 ;
      real x[ND_ND], time;
      time = CURRENT_TIME; // Acquire time from Fluent solver
      C_CENTROID(x, c, t); // Acquire the cell centroid location
      real T = C_T(c, t);

      pri_th = THREAD_SUB_THREAD(t, 0);
      sec_th = THREAD_SUB_THREAD(t, 1);





      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);
      real factor = (2 * rho * Cp) / (rhom * Cpm + rhog * Cpg);
      Message(“Factor = %f\n”,factor);

      real r = sqrt(pow(x[0] – x0 – v * time, 2.0) + pow(x[1] – y0, 2.0));



      if (C_VOF(c, sec_th) > 0.05 && C_VOF(c, sec_th) < 1)
      {


      source = ((2 * A * P) / (Pi * R * R)) * exp((-2 * (r * r)) / (R * R))*factor ;
      dS[eqn] = 0.0;
      }
      else
      {
      source = 0.0;
      dS[eqn] = 0.0;
      }

      return source;
      }

       

    • Kanak BUET19
      Subscriber

      Sorry Something went wrong . I said that , The volume fraction gradient calculation isnt working. Everytime i multiply the term C_UDMI(c,t,2) with source,  result becomes 0 . Any chance I might have done any mistake in the DEFINE_ADJUST part?

    • Rob
      Forum Moderator

      No idea as I don't do much coding and we don't debug. Why not just use the gradients directly? 

    • Kanak BUET19
      Subscriber

      In my code, I am taking value of  C_VOF_G . Apparently it seems in order for this to work , I need to set : solve/set/expert/Keep temporary solver memory from being feed? to YES

      but, upon doing this I found this message : 

      Info: Expert option for not freeing temporary solver memory is incompatible with adaption in parallel. 

      (Also I have used mesh adaption to patch solid domain )

      Since, fluent doesnt work in serial in recent days, I need your guidance for storing the VOF Gradient value somehow. Any suggestions? 

    • Rob
      Forum Moderator

      You may have created a register, unless you've set refinement/coarsening you've not adapted the model so you should be OK. 

    • Kanak BUET19
      Subscriber

      Yes I have created a register and I am obliged to do that for my simulation purpose. As I mentioned earlier, I needed to patch the solid domain to define two different phases. But now I need to calculate VOF gradient of the solid phase. Is there any other way to obtain VOF_G ? 

    • Rob
      Forum Moderator

      Have you tried running the solver with the code? 

    • Kanak BUET19
      Subscriber

      All this time I was just checking the contour after initialising. Never really bothered to run the simulation . After running , initially the Gradient was 0 but as soon as I started the sim , it started working!!! THANKS A LOT ROB!! Love you <3

    • Rob
      Forum Moderator

      You'll find some of the UDF calls come at start/end of a time step so it's always worth running before checking output values. 

    • Kanak BUET19
      Subscriber

       

      Hi Rob, 
       
      Thanks for the earlier suggestions. I have finally been able to run the simulation and also been able to visualize the meltpool. (added below) 
       
      I still haven’t added the Marangoni force equation yet. and for that I need to use temperature gradient value. But I am facing a problem. 
       
      Here’s a brief summary of my problem : 
       
      When inside the DEFINE_ADJUST function , I try to add this following line : 
       
      C_TEMP_G_X(c,t) = C_T_G(c,t)[0] ; 
       
      After running the simulation fluent crashes instantly. Basically I have renamed the UDMI earlier and now trying to apply the gradient on that UDMI . Any suggestions why is it happening?
       
      NOTE : I have alloted sufficient UDMI mannually in the GUI 
       
      I renamed it like that : 
       
      #include “udf.h”
      …..
      …..
       
      #define C_TEMP_G_X(c, t) C_UDMI(c, t, 8) // Renaming the UDMI 
       
      DEFINE_ADJUST(adjust_gradient_heat, domain)
      {
      … ….
      C_TEMP_G_X(c,t) = C_T_G(c,t)[0] ; // Applying X axis temp gradient into the renamed UDMI 
       
       
      }
       
       
       
       
       

       

    • Rob
      Forum Moderator

      Does it work if you just use C_UDMI = C_T  with all of the (c,t) bits?  Making up labels that are similar to something Fluent may use can be a little risky. 

    • Kanak BUET19
      Subscriber

      I actually figured out the problem. The issue was I forgot to add the below portion inside the DEFINE_ADJUST code. Thanks though ! 

       

      Alloc_Storage_Vars(domain, SV_T_RG, SV_T_G, SV_NULL);
      T_derivatives(domain);
      Free_Storage_Vars(domain, SV_T_RG, SV_NULL);
Viewing 15 reply threads
  • You must be logged in to reply to this topic.