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.

How to model Selective Laser Melting in Fluent?

TAGGED: 

    • Dubey92
      Subscriber

      I am starting to model Selective Laser melting/Laser Powder Bed Fusion in Fluent. I have read published works and have seen that it can be modelled in Fluent. I have learnt that it can be modelled using Solidification/Melting and VoF in Fluent. To add the source terms, I need to write UDFs. The main issue I am facing is in designing the model from scratch. I am facing problem in designing the inert gas domain and solid metal below. How to model these two domains together? I have also learnt that the solid part can be modelled as a fluid of high viscosity. But I am unable to start the design of the model. Please help me. I am running out of time, so any help is much appreciated.

    • Rob
      Forum Moderator
      Gas-liquid can be modelled with VOF, that's a multiphase model. Note there are limitations re radiation and the free surface so read the manual.
      The solidification/melting model works as you mention. We assume the solid isn't moving by numerical means. When it gets hot enough it'll melt. So the melting "solid" is also a fluid.

    • Dubey92
      Subscriber
      Thank you very much for your reply. I am not targeting re radiation at this point. And also, I am assigning a fluid to the metal domain also. The fluid is initially a fluid with high viscosity and when it melts, its viscosity changes. The main issue I am facing is how to model inert gas domain above the metal domain? Should I use the "Add Frozen" feature and add a separate domain of inert gas above the metal. How to assign different volume fractions to the gas and metal domain. I tried to model using add frozen method, two different domains of gas and metal one above the other. I named one velocity inlet in the gas domain and one pressure outlet for the gas domain. The other faces I assigned wall BC. Now, the issue is with the interface of the two domains. Fluent is automatically assigning it a Wall BC. Will giving it a marangoni stress work? Please help!!
    • Rob
      Forum Moderator
      Read up on the VOF model. Then click on Help and do the tutorials. "Add frozen" is a DesignModeler term, and may or may not solve your problem depending on why you're doing it.
    • Dubey92
      Subscriber
      Thank you very much for your inputs.
    • Dubey92
      Subscriber
      I have written the UDF for energy source term comprising of Laser heat, Convection and radiation terms.
      #include "udf.h"
      #include "sg_mphase.h"
      #include "mem.h"
      #include "sg_mem.h"
      #include "math.h"
      #include "flow.h"
      #include "unsteady.h"

      #define A 0.4// Absorption coefficient
      #define P 200// Laser power
      #define R 80e-6// spot radius
      #define v 0.1// scan speed of laser
      #define h 25// Heat transfer coefficient
      #define Ta 298// Ambient air temperature
      #define s 5.67e-8// Stefan Boltzmann constant
      #define e 0.5// Emmisivity
      #define Pi 3.1415926535
      #define Ts 1658// Solidus temperature
      #define Tl 1723// Liquidus temperature
      #define x0 100e-6// Initial x position of the laser
      #define y0 0.0// Intiial y position of the laser
      #define domain_ID 3// Domain ID of metal substrate


      DEFINE_INIT(volume_fraction, mixture_domain)
      {
      int phase_domain_index = 1;
      cell_t c;
      Thread *t;
      Domain *subdomain;
      real xc[ND_ND];
      sub_domain_loop(subdomain, mixture_domain, phase_domain_index)
      {
      if(DOMAIN_ID(subdomain) == 3)
      thread_loop_c (t,subdomain)
      {
      begin_c_loop_all(c,t)
      {
      C_CENTROID(xc,c,t);
      if(xc[0] > -0.5e-3 && xc[0] < 0.5e-3 && xc[1] > -0.25e-3 && xc[1] < 0.25e-3 && xc[2] < 0 && xc[2] > -0.3e-3)
      C_VOF(c,t) = 1.0;
      else
      C_VOF(c,t) = 0.0;
      }
      end_c_loop_all(c,t)
      }
      }
      }




      DEFINE_ADJUST(adjust_gradient, domain)
      {
      Thread *t;
      cell_t c;
      domain = Get_Domain(domain_ID);

      thread_loop_c(t, domain)
      {
      begin_c_loop(c,t)
      {
      C_UDSI(c,t,0) = C_VOF(c,t);
      }
      end_c_loop(c,t)
      }
      }

      DEFINE_ON_DEMAND(store_gradient)
      {
      Domain *domain;
      cell_t c;
      Thread *t;
      domain = Get_Domain(domain_ID);

      thread_loop_c(t, domain)
      {
      begin_c_loop(c,t)
      {
      C_UDMI(c,t,0) = NV_MAG(C_UDSI_G(c,t,0));
      }
      end_c_loop(c,t)
      }
      }



      DEFINE_SOURCE(heat_source, c, t, dS, eqn) // The name of the UDF is heat_source
      {
      real source;
      real x[ND_ND], time; // Define face centroid vector, distance, time, exponential for laser and volume to get cell volume
      time = RP_Get_Real("flow-time");// Acquire time from Fluent solver
      C_CENTORID(x, c, t); // Acquire the cell centroid location
      real T = C_T(c,t);


      if(C_VOF(c,t)>0.05 && C_VOF(c,t)<1)
      {
      source = (((2*A*P)/(Pi*R*R))*exp((-2*(pow(x[0]-x0-v*time,2.0) + pow(x[1]-y0,2.0)))/(R*R)) - h*(T-Ta) - s*e*(pow(T,4) - pow(Ta,4)))*C_UDMI(c,t,0);
      dS[eqn] = 0.0;
      }
      else
      {
      source = 0.0;
      dS[eqn] = 0.0;
      }
      return source;
      }
      On compiling, I am receiving the error: Creating library libudf.lib and object libudf.exp
      heat_source.obj : error LNK2019: unresolved external symbol C_CENTORID referenced in function heat_source
      libudf.dll : fatal error LNK1120: 1 unresolved externals
      Can someone please help!! And also this is the first time I am writing a UDF, so it would be really helpful if someone can tell me if this is the right way for writing an energy source term for laser heating in welding or SLM. I have used two phases, one for the inert gas and other for metal substrate.
      Thank you
    • Dubey92
      Subscriber
      Sorry, it was spelling mistake. It has compiled now but still it would be really helpful if someone could tell me is this the right way for writing UDF for energy source term in VoF?
    • YasserSelima
      Subscriber
      to call C_VOF, you need to use sub thread ... you need to use THREAD_SUB_THREAD . Look it up in the manual
    • Dubey92
      Subscriber
      Thanks for your input. I will look into it. Also, can you tell how to model the inert gas and metal substrate? Are they modelled with two separate domain(the inert gas above the metal substrate) or a single domain is designed and metal is assigned volume fraction using patch or UDF?
    • YasserSelima
      Subscriber
      You can use single domain and batch the inert gas VOF to 1 at the top and the rest, batch it with solid.
    • Dubey92
      Subscriber
      Thanks very much for your input. I have made a single domain. I am modeling 2 fluids, one for the inert gas and the other for the metal. I am giving a high viscosity to the metal substrate when it is in solid phase. And lower part I have patched with metal volume fraction of 1.
    • Dubey92
      Subscriber
      Sorry to disturb you all again. It's just that I am very new to UDF and running out of time due the loss caused due to the pandemic. My work is modeling SLM and I am trying to start with melting of a solid block with inert gas above the substrate. I have attached my model and UDF. I have written the UDF by taking help from this forum and other sources.
      I am trying to add this magnitude of gradient of volume fraction in the energy equation as shown. The UDF compiles without any error and initializes also without any error. When I run the simulation, Fluent crashes with the errors shown in the image below. I have attached my UDF also. I would be really grateful if someone could help me with this. I am new to UDFs and perhaps have made a mistake in writing it.
      #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"

      #define A 0.4// Absorption coefficient
      #define P 200// Laser power
      #define R 80e-6// spot radius
      #define v 0.1// scan speed of laser
      #define h 25// Heat transfer coefficient
      #define Ta 298// Ambient air temperature
      #define s 5.67e-8// Stefan Boltzmann constant
      #define e 0.5// Emmisivity
      #define Pi 3.1415926535
      #define Ts 1658// Solidus temperature
      #define Tl 1723// Liquidus temperature
      #define x0 100e-6// Initial x position of the laser
      #define y0 0.0// Intiial y position of the laser
      #define domain_ID 3// Domain ID of metal substrate


      DEFINE_INIT(volume_fraction, mixture_domain)
      {
      int phase_domain_index = 1;
      cell_t c;
      Thread *t;
      Domain *subdomain;
      real xc[ND_ND];
      sub_domain_loop(subdomain, mixture_domain, phase_domain_index)
      {
      if(DOMAIN_ID(subdomain) == 3)
      thread_loop_c(t,subdomain)
      {
      begin_c_loop_all(c,t)
      {
      C_CENTROID(xc,c,t);
      if(xc[0] > -0.5e-3 && xc[0] < 0.5e-3 && xc[1] > -0.25e-3 && xc[1] < 0.25e-3 && xc[2] < 0 && xc[2] > -0.3e-3)
      C_VOF(c,t) = 1.0;
      else
      C_VOF(c,t) = 0.0;
      }
      end_c_loop_all(c,t)
      }
      }
      }

      DEFINE_ADJUST(adjust_gradient, mixture_domain)
      {
      int phase_domain_index = 1;
      Thread *t;
      cell_t c;
      Domain *subdomain = DOMAIN_SUB_DOMAIN(mixture_domain,phase_domain_index);
      sub_domain_loop(subdomain, mixture_domain, phase_domain_index)
      {
      if(DOMAIN_ID(subdomain) == 3)
      thread_loop_c(t, subdomain)
      {
      begin_c_loop(c,t)
      {
      C_UDSI(c,t,0) = C_VOF(c,t);
      C_UDMI(c,t,1) = C_UDSI_G(c,t,0)[0];
      C_UDMI(c,t,2) = C_UDSI_G(c,t,0)[1];
      C_UDMI(c,t,3) = C_UDSI_G(c,t,0)[2];
      C_UDMI(c,t,4) = sqrt(C_UDMI(c,t,1)*C_UDMI(c,t,1) + C_UDMI(c,t,2)*C_UDMI(c,t,2) + C_UDMI(c,t,3)*C_UDMI(c,t,3));
      }
      end_c_loop(c,t)
      }
      }
      }
      DEFINE_SOURCE(heat_source, c, t, dS, eqn) // The name of the UDF is heat_source
      {
      Thread *pri_th;
      Thread *sec_th;
      real source;
      real x[ND_ND], time; // Define face centroid vector, distance, time, exponential for laser and volume to get cell volume
      time = RP_Get_Real("flow-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);

      if(C_VOF(c,t)>0.05 && C_VOF(c,t)<1)
      {
      source = (((2*A*P)/(Pi*R*R))*exp((-2*(pow(x[0]-x0-v*time,2.0) + pow(x[1]-y0,2.0)))/(R*R)) - h*(T-Ta) - s*e*(pow(T,4) - pow(Ta,4)))*C_UDMI(c,t,4);
      dS[eqn] = 0.0;
      }
      else
      {
      source = 0.0;
      dS[eqn] = 0.0;
      }
      return source;
      }
      I request you all to please help as after this I need to modify the momentum equation also and move forward with adding particles in the domain.
    • Rob
      Forum Moderator
      Have you switched on enough UDM in the solver? It's not automatic.
    • Dubey92
      Subscriber
      Yes Sir, I have allocated 10 UDMs in the solver(I think more than required). The code shows no error on compiling and initialization. When I run using calculate in "Run Calculation", FLUENT writes somethings and then crashes with the error.
      This is the error and then FLUENT window closes automatically. Can you suggest something? Is my code to store the VOF gradient right? The initialization code is working fine.
    • Rob
      Forum Moderator
    • Rob
      Forum Moderator
      Do NOT post questions in multiple threads. If you do have separate questions keep them that way and don't mix and match.
Viewing 15 reply threads
  • The topic ‘How to model Selective Laser Melting in Fluent?’ is closed to new replies.