首页/文章/ 详情

Fluent案例:利用VOF+凝固熔化+UDF实现激光焊熔池模拟

7月前浏览1264

案例描述          

利用VOF+凝固熔化+UDF对激光焊熔池过程的模拟,该过程中包括金属材料的相变、激光热源加热、热源移动等物理变化过程。通过UDF完整地模拟了激光焊接过程中的热源加热、熔池流动、反冲压力效应、表面张力变化和浮力效应等关键物理现象。构建模型如下图所示,模型的正面为对称面,其他均为壁面,焊接的起始点为(-3.5,0,0),激光热源的移动速度为0.01m/s(文末附案例文件获取方式)。      

     


步骤      

1.导入网格模型      

导入模型网格文件,如下图所示:      

     


2.通用设置      

采用压力基求解器,瞬态求解,重力方向为z的负方向。      

     


3. 模型选择      

开启能量方程,粘性模型选择层流,开启凝固和熔化模型并保持默认设置。      

     

     


4. UDF加载      

添加udf.c源文件,点击编译并加载。      

     


UDF完整地模拟了激光焊接过程中的热源加热、熔池流动、反冲压力效应、表面张力变化和浮力效应等关键物理现象。注意:UDF定义焊接速度的过程中,速度的定义并非热源点的移动速度,而是计算域的移动速度。      




















































































































































































































#include "udf.h"    #include "sg_mphase.h" // 多相流相关的头文件#include "math.h" // 数学函数库#include "sg.h" // 源项和梯度相关头文件#include "flow.h" // 流动相关头文件#include "mem.h" // 内存管理头文件#include "metric.h" // 几何度量相关头文件// 定义常数宏#define v 0.01            /*焊接速度*/           // 焊接速度 0.01 m/s#define L 0.006            /*工件厚度*/          // 工件厚度 0.006 m#define T_SAT 2700             /* 汽相线 */      // 汽化温度 2700K#define P 3000                  // 激光功率 3000W#define n 0.9             /*热效率*/             // 热效率 90%#define PI 3.141592653          // 圆周率 π#define R0 0.0006     /*热源加热斑点半径*/        // 热源半径 0.0006 m#define Re 4.5E6               /* recoil—_pressure系数 */  // 反冲压力系数#define Ree 0.5                /* recoil—_pressure系数 */  // 反冲压力系数(x,y方向)#define Reez 1                 /* recoil—_pressure系数 */  // 反冲压力系数(z方向)#define xx0 0.0035             // 热源初始位置偏移量//激光热源函数DEFINE_SOURCE(laser_source,c,t,dS,eqn)// 定义热源项,Fluent UDF 标准格式{    real xc[ND_ND],x,y,z,time,Q,r,H,source;  // 声明变量:坐标、时间、功率、半径、深度、源项    Thread *sec_th;                          // 声明第二相线程指针    sec_th=THREAD_SUB_THREAD(t,1);           // 获取第二相线程(多相流中的气相)    time=RP_Get_Real("flow-time");           // 获取当前流动时间    C_CENTROID(xc, c, t);                    // 获取当前网格单元的中心坐标    x=xc[0]+xx0-v*time;                      // 计算移动热源的x坐标(考虑焊接速度,速度的定义并非热源点的移动速度,而是计算域的移动速度)    y=xc[1];                                 // y坐标    z=xc[2];                                 // z坐标    H=0.003;                              /* 热源深度*/  // 定义热源作用深度    r=sqrt(x*x+y*y);                       // 计算点到热源中心的水平距离    Q=n*P;                                 // 计算有效功率 Q = 效率 × 功率    if(r<=R0&&z<=0&&z>=-H)                 // 判断条件:在热源半径内且在深度范围内    {        // 高斯旋转体热源模型        source=9*Q/(PI*R0*R0*H*0.95)*exp(-6/(log(H/(-z))*R0*R0)*r*r);        dS[eqn]=0;                         // 源项对变量的导数为0(常数源项)    }    else    {        source=0;                          // 在热源范围外,源项为0        dS[eqn]=0;                         // 导数为0    }    return source;                         // 返回热源项值}//VOF梯度存储函数DEFINE_ADJUST(store_VOF_gradient,domain)// 定义调整函数,在每个时间步执行{    Thread *t;                             // 线程指针    Thread *ppt;                           // 主相线程指针    Thread **pt;                           // 线程指针数组    cell_t c;                              // 网格单元标识符    int phase_domain_index=1;              // 相域索引    Domain *pDomain = DOMAIN_SUB_DOMAIN(domain,phase_domain_index);  // 获取子域    // 分配存储空间用于VOF梯度计算    Alloc_Storage_Vars(pDomain,SV_VOF_RG,SV_VOF_G,SV_NULL);    // 重构VOF标量场    Scalar_Reconstruction(pDomain, SV_VOF,-1,SV_VOF_RG,NULL);    // 计算VOF梯度    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))             // 如果是流体线程        {            ppt = pt[phase_domain_index];  // 获取主相线程            begin_c_loop (c,t)             // 开始单元循环            {                // 将VOF梯度分量存储到UDM中                C_UDMI(c,t,0) = C_VOF_G(c,ppt)[0];  // x方向梯度                C_UDMI(c,t,1) = C_VOF_G(c,ppt)[1];  // y方向梯度                  C_UDMI(c,t,2) = C_VOF_G(c,ppt)[2];  // z方向梯度            }            end_c_loop (c,t)               // 结束单元循环        }    }    // 释放存储空间    Free_Storage_Vars(pDomain,SV_VOF_RG,SV_VOF_G,SV_NULL);}//X方向反冲压力源项DEFINE_SOURCE(x_recoil_source,c,t,dS,eqn){    real xc[ND_ND],x,y,z,r,time,T,xfen,recoil,x_source;  // 声明变量    Thread *sec_th;    sec_th=THREAD_SUB_THREAD(t,1);          // 获取第二相线程    T=C_T(c,t);                             // 获取当前单元温度    time=RP_Get_Real("flow-time");          // 获取当前时间    C_CENTROID(xc, c, t);                   // 获取单元中心坐标    x=xc[0]+xx0-v*time;                     // 计算移动坐标    y=xc[1];    z=xc[2];    r=sqrt(x*x+y*y);                        // 计算到热源中心距离    // 计算x方向界面法向分量(归一化)    xfen=C_UDMI(c,t,0)/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)+0.00000001);    if(r<=0.001)                            // 在反冲压力作用半径内    {        // 条件:温度达到汽化点且在气液界面区域        if(T>=T_SAT&&C_VOF(c,sec_th)>=0.1&&C_VOF(c,sec_th)<=0.9) //反冲压力必须施加在第二相上,0表示第一相-空气相        {            // 反冲压力计算(基于温度的经验公式)            recoil=3.35*Re*exp(12.37*(T-T_SAT)/T);            x_source=recoil*xfen;           // x方向反冲压力分量            C_UDMI(c,t,3)=x_source;         // 存储到UDM3        }        else            x_source=0;                     // 不满足条件时源项为0    }    else    {        x_source=0;                         // 在作用半径外源项为0    }    return x_source*Ree;                    // 返回x方向反冲压力源项}//Y方向反冲压力源项DEFINE_SOURCE(y_recoil_source,c,t,dS,eqn){    real xc[ND_ND],x,y,z,r,time,T,yfen,recoil,y_source;    Thread *sec_th;    sec_th=THREAD_SUB_THREAD(t,1);    T=C_T(c,t);    time=RP_Get_Real("flow-time");    C_CENTROID(xc, c, t);    x=xc[0]+xx0-v*time;    y=xc[1];    z=xc[2];    r=sqrt(x*x+y*y);    // 计算y方向界面法向分量    yfen=C_UDMI(c,t,1)/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)+0.00000001);    if(r<=0.001)    {        if(T>=T_SAT&&C_VOF(c,sec_th)>=0.1&&C_VOF(c,sec_th)<=0.9)        {            recoil=3.35*Re*exp(12.37*(T-T_SAT)/T);            y_source=recoil*yfen;           // y方向反冲压力分量            C_UDMI(c,t,4)=y_source;         // 存储到UDM4        }        else            y_source=0;    }    else    {        y_source=0;    }    return y_source*Ree;                    // 返回y方向反冲压力源项}//Z方向反冲压力源项DEFINE_SOURCE(z_recoil_source,c,t,dS,eqn){    real xc[ND_ND],x,y,z,r,time,T,zfen,recoil,z_source;    Thread *sec_th;    sec_th=THREAD_SUB_THREAD(t,1);    T=C_T(c,t);    time=RP_Get_Real("flow-time");    C_CENTROID(xc, c, t);    x=xc[0]+xx0-v*time;    y=xc[1];    z=xc[2];    r=sqrt(x*x+y*y);    // 计算z方向界面法向分量    zfen=C_UDMI(c,t,2)/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)+0.00000001);    if(r<=0.001)    {        if(T>=T_SAT&&C_VOF(c,sec_th)>=0.1&&C_VOF(c,sec_th)<=0.9)        {            recoil=3.35*Re*exp(12.37*(T-T_SAT)/T);            z_source=recoil*zfen;           // z方向反冲压力分量            C_UDMI(c,t,5)=z_source;         // 存储到UDM5        }        else            z_source=0;    }    else    {        z_source=0;    }    return z_source*Reez;                   // 返回z方向反冲压力源项(不同系数)}//表面张力属性定义DEFINE_PROPERTY(surf_tension,c,t){    real surf;    int curr,i,j;    real temp1=C_T(c,t);                    // 获取当前单元温度    if(temp1>=930)                          // 温度 ≥ 930K        surf=1.0-0.0003*(temp1-930);        // 线性减小    else if(temp1>=2730)                    // 温度 ≥ 2730K        surf=0.41;                          // 保持最小值    else        surf=1.0;                           // 低温时保持最大值    return surf;                            // 返回表面张力系数}//浮力源项DEFINE_SOURCE(fuli, cell, thread, dS, eqn){    real source;    real p, g, B, T, Tl;    T = C_T(cell, thread);                  // 获取温度    p = 2700;                               // 密度    g = -9.81;                              // 重力加速度    B = 0.0001;                             // 热膨胀系数    Tl = 930;                               // 液相线温度    if (T > Tl)                             // 温度高于液相线        source = -p * g*B*(T - Tl);         // 计算浮力源项    else        source = 0;                         // 固态时无浮力    dS[eqn] = 0;                            // 导数为0    return source;                          // 返回浮力源项}
   


5. 材料参数设置      

添加并定义金属材料,在流体材料中修改空气材料的参数并另存为金属材料,再对相关参数进行修改。其中密度、比热、导热率、粘度参数为分段线性函数。      

     

     


其中密度、比热、导热率、粘度参数定义如下:      

①密度根据温度定义4个点:300K,2700kg/m3;820K,2700kg/m3;930K,2400kg/m3;5000K,2400kg/m3;      

②比热根据温度定义4个点:300K,871J/(kg K);820K,871J/(kg K);930K,1060J/(kg K);5000K,1060J/(kg K);      

③导热率根据温度定义4个点:300K,238W/(m K);820K,238W/(m K);930K,100W/(m K);5000K,100W/(m K);      

④粘度根据温度定义2个点:930K,0.0016kg/(m s);5000K,0.0016kg/(m s)。      


添加金属材料后,定义VOF模型,表面张力系数选择UDF中定义的surf_tension。      

     

     

     

     


6.单元区域条件设置      

在单元区域设置中勾选源项,并分别添加源项的数量,包括XYZ三个方向上的反冲压力源项、Z方向上的浮力源项和一个能量源项。      

     

     

     

     

     


7.边界条件设置      

定义底部壁面的传热边界条件:      

     


定义四周壁面的传热边界条件:      

     


8.初始化      

新建一个区域标记,用于后续的局部初始化。      

     


初始化选择标准初始化,温度为300K,第二相的体积为0。局部初始化将标记出的区域第二相的体积分数设置为1。      

     


9.运行计算      

时间步数和时间步长定义如下:      

     


温度分布云图      

 

空气相体积分布云图      

     


来源:仿真与工程
Fluent多相流UDF通用UM焊接材料
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-03-12
最近编辑:7月前
余花生
签名征集中
获赞 262粉丝 610文章 397课程 0
点赞
收藏
作者推荐

温标的迷思:1℃与1K的温差相同,为何相对偏差竟天差地别?

这篇文章是我让AI帮忙写的~~包括标题、封面引言温度是物理学与工程学中最基本的物理量之一,我们在日常生活中常用摄氏度(℃),而在科学领域则常使用开尔文(K)。一个常见的困惑是:温差1℃和温差1K是否相同?另一个随之而来的深层问题是:如果绝对温差相同,为什么使用℃和K计算的“相对偏差”会相差悬殊?本文将系统梳理这两个问题的物理本质,并阐明温标选择在科学计算中的关键意义。一、温差1℃=温差1K:本质是温标的刻度间隔一致摄氏温标与开尔文温标的换算关系为:TK=T℃+273.15这个关系表明,两种温标的零点不同,但单位间隔(1度)的大小完全一致。从物理本质上讲,温度变化取决于系统热运动能量的差异,而这一差异与温标的零点无关。例如:物体从20℃升至21℃,绝对温度从293.15K升至294.15K。温差计算:21℃−20℃=1℃,294.15K−293.15K=1K因此,从温差(ΔT)的角度,1℃完全等价于1K。国际单位制中,温度变化的推荐单位是K,但数值上与℃保持相等。二、同一个温差,为何相对偏差截然不同?尽管温差相同,但当涉及到相对偏差时,使用℃和K会得出完全不同的结果,这是一个值得警惕的现象。我们先明确“相对偏差”的常用定义之一——以平均值为基准的相对变化:相对偏差=∣T2−T1∣(T1+T2)/2计算对比摄氏温标:T1=25℃,T2=35℃温差ΔT=10℃平均值=30℃相对偏差=10/30≈0.333=33.33%开尔文温标:T1=298.15K,T2=308.15K温差ΔT=10K平均值=303.15K相对偏差=10/303.15≈0.033=3.30%结果:摄氏下的相对偏差(33.33%)是开尔文下(3.30%)的约10倍。造成这种巨大差异的唯一原因,是两种温标的零点不同。三、物理本质:为何必须用绝对温度处理比例关系摄氏温标以水的冰点为零点(0℃),这仅是人为约定的参考点,而非物理上的绝对零度(-273.15℃=0K)。当使用摄氏数值计算“相对偏差”时,分母会包含相对于绝对零度的偏移,导致比例严重失真。极端例子:从1℃到2℃,温差1℃,但摄氏平均值仅1.5℃。此时相对偏差高达:1/1.5≈66.7%而同样变化在开尔文温标下(274.15K→275.15K)的相对偏差仅为:1/274.65≈0.364%可见,如果采用摄氏温度进行相对变化的评估,数值会因接近冰点而急剧放大,这在物理上并不反映真实的能量相对变化。在热力学与统计物理中,温度比例(如卡诺效率、热膨胀系数中的ΔT/T)必须使用绝对温度(K),以保证比例关系的物理一致性。四、结论与启示温差相同:1℃的温差=1K的温差,因为两种温标的分度值相同,只是零点不同。科学表达温差时通常建议用K。相对偏差不同:使用℃计算相对偏差会引入人为零点的干扰,结果依赖温标选取,物理意义模糊;使用K计算则反映真实的热运动能量比例关系。科学计算的准则:凡是涉及温度比例或相对变化的物理问题(如热传导、热力学定律、材料热膨胀等),必须使用绝对温标(开尔文)。摄氏度仅适合于日常温度描述和温差表达,不宜用于需要比例的分母中。来源:仿真与工程

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈