☰
塑性本构核心算法:从屈服准则到径向返回与UMAT实现
2026/10/6 9:48:17 网站建设 项目流程

做塑性仿真或者写材料子程序的朋友,一定被问过类似的话:“塑性本构不就是给个屈服强度,再设一条硬化曲线吗?”真要是这么简单,塑性力学和“算法”这两个词就不会天天绑在一起了。实际上,从ABAQUS跑到LS-DYNA,从回弹预测到碰撞吸能,背后那一整套“弹性预测—塑性校正—切线更新”的流程,才是让材料在程序里老老实实屈服、硬化、卸载的核心。这篇文章我想把塑性力学里最基础也最关键的计算套路讲清楚:屈服准则、流动法则、硬化规律这三件套怎么用来搭建本构,径向返回算法是怎么一步步把试算应力拉回屈服面的,以及这些理论落到UMAT里会遇到什么坑。适合刚接触塑性仿真的结构工程师、准备写材料子程序的研究生,以及那些调半天不收敛想弄明白到底哪一步写错的人。

1. 塑性力学为什么是“算”出来的:问题的起点

1.1 应力不是查表就能拿到的:塑性变形的路径依赖性

很多人在弹性力学里待习惯了,总觉得应力可以由应变直接算出来:给一个应变,乘上弹性矩阵,应力就出来了。但材料一旦进入塑性,这种“一锤子买卖”就不成立了。塑性变形的最大特点是路径依赖:同样一个最终应变状态,走的是单调拉伸路径还是加卸载循环路径,对应的应力完全不同,内部损伤和残余变形也不一样。

这么说可能有点抽象,拿生活中的例子来类比。橡皮筋拉到一定长度再松手,会回到原长,这是弹性;但一根铁丝,你弯过去它就不回来了,而且弯两次的角度不同,它“记住”的变形历史也不同。铁丝记住的这段历史,在力学里就是塑性应变、等效塑性应变、背应力这些状态变量。问题在于,这些状态变量和当前应力之间不是简单的一一对应关系,而是一连串增量过程的累积结果。

所以数值计算只能走增量路线:把整个加载过程切成很多小步,每一步只给一个应变增量 Δε,然后根据当前状态和这个增量,推算出新的应力和新的内部变量。这个推算过程,学术名称叫“本构积分”或“应力更新算法”。换句话说,弹塑性分析从一开始就依赖算法,不是经验公式,而是增量方程积分策略的产物。

这也解释了为什么很多有限元软件在塑性分析时特别容易卡住。因为程序每一步都在做面试题:当前应力在屈服面内还是屈服面外?如果已经越过屈服面,塑性应变增量该往哪个方向走?硬化参数该随哪个量演化?每一步答错,整个增量步的平衡迭代就会发散。

1.2 塑性本构里到底有哪些“算法任务”

把塑性本构塞进计算机,需要完成三件事。第一件事是应力更新:给一个应变增量,算出新的应力张量,这是本构积分算法的核心。第二件事是切线刚度计算:算出局部应力对应变的导数,也就是 ∂Δσ/∂Δε,供全局平衡迭代使用。第三件事是状态变量更新:等效塑性应变、背应力张量这些“记忆”要跟着更新,否则下一步就无从判断。

有人可能会觉得,这三件事里第一件最重要,切线算个大概就行。这是新手最常踩的坑。全局Newton迭代对局部切线非常敏感,切线给得不一致,哪怕应力更新本身算得很准,外部求解器也难以收敛,或者收敛得极慢,一步要迭代几十次。

这里多说一句,很多程序员是在面试里背KMP算法、快排、堆排序练出来的,但到了塑性力学领域,真正决定分析成败的“面试题”变成了径向返回映射。这个算法解决的问题非常朴素:试算应力跑到屈服面外面去了,怎么把它“拉”回来,同时保证屈服条件重新满足。下面的内容就是围绕这个核心展开的,先把基础概念搭起来,再一步步讲算法本身。

2. 绕不开的三件套:屈服准则、流动法则与硬化规律

2.1 屈服准则:先给材料画一条“投降线”

塑性力学第一步要回答的问题,是材料在什么应力状态下开始屈服。工程中最常用的两个准则是Tresca准则和von Mises准则。Tresca看的是最大剪应力,认为当最大剪应力达到某个临界值,材料就进入塑性。von Mises则看的是偏应力张量的第二不变量 J₂,写成等效应力的形式是:

q = sqrt(3 * s : s / 2)

其中 s 是偏应力张量。屈服条件写作 f = q − σ_y = 0,f < 0 时处于弹性状态,f = 0 时处于屈服状态,理论上不允许 f > 0 出现,一旦出现就说明当前应力状态超出了屈服面,需要用塑性修正拉回来。

为什么金属塑性分析几乎都用von Mises而不是Tresca?因为von Mises屈服面是光滑的,不存在棱角,数学处理方便,流动方向唯一确定,数值上也稳定。Tresca屈服面是六边形,角点处法线方向不唯一,程序处理起来麻烦得多。从物理上看,von Mises对金属的拟合精度也很好,尤其适合韧性金属的初始屈服描述。

一个特别容易犯的错误,是把抗拉强度直接填进材料卡片当σ_y。拉伸试验测到的抗拉强度对应的是材料在颈缩前后的最大承载,而不是初始屈服点。塑性本构里的σ_y应该是比例极限或者取0.2%残余应变对应的条件屈服强度,两者差别很大,填错了整个塑性段都跟着错。

2.2 流动法则:塑性应变增量的方向由谁决定

知道何时屈服还不够,还得知道屈服以后塑性应变是怎么发展的。这里就要用到流动法则。金属材料最常用的是相关联流动法则,塑性应变增量方向垂直于屈服面,数学上写作:

dεp = dλ * ∂f / ∂σ

∂f/∂σ 是屈服函数对应力的梯度,dλ 是塑性乘子,是个非负标量,控制塑性变形的大小。对von Mises屈服函数做梯度运算会发现,塑性应变增量方向恰好与当前偏应力方向一致。这一点非常关键,它是径向返回算法能保持“径向”的根本原因。

流动法则还顺带解释了金属塑性体积不变的现象:塑性应变增量方向是纯偏量的,不包含体积分量,所以金属材料在大塑性变形下体积基本不变。这也是为什么在大多数金属塑性算法中,静水压力部分仍然按弹性处理,只有偏斜部分参与塑性修正。

非相关联流动法则在岩土和混凝土里更常见,塑性应变方向不再垂直于屈服面,而是垂直于另一个叫“塑性势函数”的面。这样做是为了描述剪胀、摩擦这类金属中没有的现象。但如果你做的是金属结构分析,先用相关联流动就足够,不要一上来就引入额外的塑性势参数,否则参数标定会复杂到让你怀疑人生。

2.3 硬化规律:屈服面会变、会动,别写死

材料屈服之后,如果要继续增加应力,通常需要更高的应力水平,这说明屈服面在演化。最常见的两种描述是各向同性硬化和随动硬化。

各向同性硬化最简单,屈服面在应力空间中均匀膨胀,屈服应力是等效塑性应变的函数。σ_y = σ_y0 + H' * ε̄p 是线性硬化形式,其中 H' = dσ_y/dε̄p,代表屈服应力随等效塑性应变增长的速率。这个形式适合单调加载问题,比如拉伸、压缩、胀形这类载荷方向不变的工况。

随动硬化则描述屈服面中心发生平移,引入背应力张量 α,屈服函数变成 f(σ − α) − σ_y0 = 0。屈服面的大小不变,但在应力空间里整体移动。这样做能捕捉包辛格效应:材料在一个方向加载硬化后,反向加载时屈服应力会降低。这个效应在回弹、疲劳、循环加载分析里非常重要。

实际工程分析更常用组合硬化,也就是各向同性部分和随动部分同时生效。我见过不少工程师在ABAQUS里做回弹分析,材料参数只给了等向硬化,结果回弹量跟实验差得离谱,换用包含随动硬化的组合模型之后才对上。原因很简单,回弹本质是卸载路径上的应力重新分布,卸载过程中材料内部应力反向,此时背应力的演化直接决定残余应力状态。

还有一点新手容易弄混:H'是硬化模量,不是弹性模量,也不是切线模量。H'描述的是屈服应力随等效塑性应变的增长率,单位是MPa,但它跟应力-应变曲线的切线斜率完全是两个概念。曲线斜率是 E_t = E H' / (E + H'),需要经过弹塑性关系换算,不能拿曲线的dσ/dε直接当H'填进程序。这个换算关系在参数标定那一节再展开。

3. 核心算法:弹性预测-塑性校正(径向返回算法)

3.1 为什么叫“径向返回”

有了屈服面、流动法则和硬化规律,终于可以讲算法了。当前增量步开始时,假设材料处于已知状态,给一个应变增量 Δε,第一步先按弹性关系试算一个新应力,这叫试探应力(trial stress):

σ_trial = σ_n + C : Δε

其中 C 是弹性刚度张量。这个试算应力大概率不在屈服面上,如果它落在屈服面内,说明这个增量步材料还处于弹性卸载或纯弹性加载,直接把 σ_trial 当结果用就行。但如果 f_trial = q_trial − σ_y(ε̄p_n) 大于0,说明试算应力已经越过屈服面,这在物理上不允许,必须进行塑性修正。

修正的方法很巧妙,得益于von Mises屈服面是球形这一特性:塑性流动方向与偏应力相同,所以修正过程就是把试算偏应力沿着径向缩回到屈服面上。这就像你拿着一个气球往墙上压,气球的投影点被压回球面,修正方向始终指向圆心那一侧,所以叫径向返回。

这个算法最妙的地方在于,它把一个张量方程降维成了一个标量方程。你不需要联立求解9个应力分量,只需要求解一个未知量——塑性乘子增量 Δγ,然后所有应力分量都通过这个标量统一更新。这也是径向返回算法在工程软件里成为绝对主流的根本原因。

3.2 一步步走通径向返回算法

下面按步骤拆解一个标准的J2径向返回流程。这里以各向同性硬化的von Mises模型为例。

第一步,计算试算偏应力。先算体积应变和偏应变,再用剪切模量算试算偏应力 s_trial,同时更新试算屈服应力。第二步,计算试算Mises等效应力 q_trial = sqrt(1.5 * s_trial : s_trial),把它和当前屈服应力比较。如果 f_trial = q_trial − σ_y ≤ 0,直接弹性更新收工。如果 f_trial > 0,进入塑性修正。

第三步是核心,求解塑性乘子。对于线性硬化材料,一致性条件可以写成:

q_trial − 3G Δγ = σ_y0 + H' (ε̄p_n + Δγ)

化简后得到解析解:

Δγ = (q_trial − σ_y0 − H' ε̄p_n) / (3G + H')

公式里的3G是因为Mises等效应力 q 与剪切模量 G 之间存在系数关系,径向收缩的速率是3GΔγ,不是2GΔγ。很多实现卡在这里,系数写错之后的应力结果看起来也对,但一对比就差了30%甚至更多。

得到Δγ之后,第四步更新应力。偏应力按比例回缩,回缩系数是 1 − 3G Δγ / q_trial:

s_new = (1 − 3G Δγ / q_trial) * s_trial

体积应力部分保持弹性不变,叠加回去就得到新应力张量。第五步更新状态变量:等效塑性应变增加Δγ,其他如背应力按各自演化方程更新。

这里放一段可以直接运行验证的Python实现,适合第一次写径向返回的朋友对照学习:

import numpy as np def radial_return_J2(s_trial, eps_bar_p, G, sig_y0, H_prime): q_trial = np.sqrt(1.5 * np.dot(s_trial, s_trial)) f_trial = q_trial - (sig_y0 + H_prime * eps_bar_p) if f_trial <= 0.0: return s_trial, eps_bar_p, 0.0 dgamma = f_trial / (3.0 * G + H_prime) factor = 3.0 * G * dgamma / q_trial s_new = s_trial * (1.0 - factor) return s_new, eps_bar_p + dgamma, dgamma

这段代码输入试算偏应力和当前等效塑性应变,输出新的偏应力、更新的等效塑性应变和塑性乘子。你在单元级别做验证时,就可以用这个函数替换复杂的张量更新,先跑通单点行为,再嵌入有限元框架。

如果硬化规律是非线性的,比如饱和指数硬化 σ_y = σ_y0 + Q(1 − exp(−b ε̄p)),就不能直接解解析式了,需要对一致性条件做Newton迭代。迭代函数是:

g(Δγ) = q_trial − 3G Δγ − σ_y(ε̄p_n + Δγ) = 0

迭代格式是标准的Newton-Raphson:

Δγ_new = Δγ_old − g(Δγ_old) / g'(Δγ_old)

其中 g' = −3G − H'(ε̄p_n + Δγ),H'来自硬化曲线的当前斜率。这个迭代通常三五步就收敛,注意给初值,比如直接用弹性试算的 f_trial / (3G + H'0) 作为初值,能避免大幅震荡。

3.3 一致性切线模量:全局收敛的“加速器”

局部应力更新做好之后,还有一个同样重要的东西:一致性切线模量。它描述的是最终应力对最终应变的导数,用于有限元外层Newton迭代组装全局刚度矩阵。

很多人第一次写UMAT时,图省事直接返回弹性刚度阵,认为反正应力更新是准的,切线凑合一下就行。实测下来,结果是大变形分析几乎推不动,收敛缓慢到让人想砸电脑。因为外层的Newton迭代依赖切线信息来预测下一步位移修正量,切线不匹配,就得靠一次又一次的迭代去“试错”,一旦载荷步偏大就发散。

我建议初次实现时,可以先返回弹性切线跑通流程,但心里要清楚这只是权宜之计,最终必须换成一至切线模量。J2模型的一致性切线模量有经典推导,体积部分保持弹性,剪切部分被一个与Δγ相关的因子缩放,再叠加上沿流动方向的一阶修正。如果不想自己推,建议直接查阅Simo和Hughes在计算塑性力学中的经典教材,里面有完整张量表达式。

一个重要的物理直觉:进入塑性后,单轴切线模量从弹性模量E降为 E_t = E H' / (E + H'),所以全局刚度会显著软化。在力控制加载下,如果切线模量给不准,结构可能会出现载荷-位移响应突变,轻则迭代震荡,重则分析直接终止。这也是为什么我说,塑性问题里“算法”不是加分题,是保命题。

4. 从理论到程序:Abaqus UMAT里跑通塑性算法

4.1 UMAT骨架与变量说明:拿到手上就能改

理论讲完了,总得落地到代码。以Abaqus UMAT为例,它本质上是一个用户定义的材料本构接口,每个积分点在每个增量步都被调用一次,给你当前的应变增量DSTRAN、状态变量STATEV、材料参数PROPS,要求你返回新的应力STRESS和一致切线刚度DDSDDE。

最关键的一点,DSTRAN是增量,不是全量。我见过有人拿全应变去做径向返回,结果应力越算越大。正确做法是先把应力更新到当前增量步末尾,再存回STRESS,状态变量也跟着更新。

一个可以用的J2等向硬化UMAT骨架大致长这样:

SUBROUTINE UMAT(STRESS, STATEV, DDSDDE, SSE, SPD, SCD, 1 RPL, DDSDDT, DRPLDE, DRPLDT, 2 STRAN, DSTRAN, TIME, DTIME, TEMP, DTEMP, 2 PREDEF, DPRED, CMNAME, NDI, NSHR, NTENS, 2 NSTATV, PROPS, NPROPS, COORDS, DROT, PNEWDT, 2 CELENT, DFGRD0, DFGRD1, NOEL, NPT, LAYER, KSPT, 2 KSTEP, KINC) C C 声明变量,读入材料参数 E = PROPS(1) ANU = PROPS(2) SIGY0 = PROPS(3) HPRIME = PROPS(4) C C 计算弹性刚度矩阵,存入DDSDDE作为初值 C 弹性预测:由STRESS和DSTRAN计算trial应力 C 屈服判断:调用Mises等效应力函数 C 塑性修正:求解dgamma,更新STRESS和STATEV C 更新DDSDDE为一致切线模量 C RETURN END

这只是一个框架,核心的trial stress计算、屈服判断、径向返回、切线更新都需要自己补全。给个建议:先把状态变量定义清楚。STATEV(1)存等效塑性应变,STATEV(2)到(7)存塑性应变分量或者背应力分量,别只存一个标量。后面调试时你才能从Job后处理里看到内部变量演化。

材料参数方面,E、ν、初始屈服应力σ_y0、硬化模量H'要分开传。不要把σ_y0写成抗拉强度,也不要把硬化曲线上的总应力直接当成H'。Abaqus自带的塑性模型填的是真实应力-塑性应变数据点,而UMAT里如果你用线性硬化,H'等于屈服应力对塑性应变的导数,两者口径要分清楚。

4.2 收敛失败的排查清单:我踩过的三个大坑

塑性UMAT调试阶段,失败是常态,能一次跑通反而不正常。下面这张表是我在实际项目里总结出来的高发问题,按发生频率排序。

症状常见原因处理办法
分析一开始就中断,提示负特征值初始增量步过大,或DDSDDE与应力更新不一致减小初始增量步,打开自动增量控制
局部迭代不收敛,塑性乘子反复震荡Newton迭代初值给得离谱用弹性解的Δγ作为初值,必要时加二分法保护
收敛极慢,每步迭代次数暴增切线模量还是弹性阵,或硬化参数错误换成一致切线模量,核对H'定义
应力状态明显偏离理论解屈服判断或体积-偏量分离出错打印trial应力、q_trial和更新后的应力,单点手算
大变形问题结果不收敛忘记打开几何非线性打开NLGEOM,检查DFGRD0、DFGRD1的处理

第一个坑是初始增量步。我在一次薄板拉延仿真里,初始增量步设为总时间的10%,结果积分点应力直接飞到屈服面外十几个MPa,径向返回都拉不回来。后来把初始增量压到1%,配合自动增量很快跑通。记住一个经验:带强非线性的塑性分析,初始增量步宁可小,也不要赌。

第二个坑是Newton迭代的保护。径向返回的最终方程是单变量方程,看起来简单,但非线性强的时候也会震荡。我自己习惯先用线性化解析式估算Δγ初值,然后迭代时检查g(Δγ)符号变化,一旦发现震荡就切到二分法。工程分析要的是稳定,不是炫技。

第三个坑是单位制。UMAT不像Abaqus界面里的材料卡片有单位提醒,你传进去的值全看你自己。我曾经犯过把E写成GPa、硬化模量写成MPa的蠢事,结果应力结果整整差了三个数量级。Unity个制,写在代码注释第一行,能救命。

4.3 参数标定与验证建议:光能收敛还不行,结果要对

UMAT能跑通只是第一步,结果正确才是最终目标。我建议拿到一个新硬化模型,先做单单元验证:一个单元,单轴拉伸,查看应力-应变曲线能否复现理论解。等向硬化J2模型在单轴拉伸下的响应应该是:弹性段、屈服平台或硬化段、完全卸载后残余应变不为零。如果曲线形态不对,多半是体积-偏量分离或硬化参数标定出了问题。

单轴验证通过之后,再做循环加载验证随动硬化。两个方向加载,观察反向屈服是否提前出现,这就是包辛格效应的表现。如果反向加载屈服应力跟初始屈服应力一样高,说明背应力根本没有更新,快去检查流动法则写没写对。

参数标定阶段,最关键的是把硬化曲线从工程应力-应变换算成真实应力-塑性应变。工程应力 σ_eng = F/A0,真实应力 σ_true = σ_eng(1 + ε_eng)。塑性应变 εp = ε_true − σ_true/E。换算之后再对塑性段求斜率,得到H'。如果你直接拿工程应力曲线上的斜率当H'填进UMAT,大变形阶段误差会非常明显。

最后提一个实战技巧。我在UMAT里都会预留一个调试开关,DEBUG = 1时,每个增量步把trial应力、Δγ、更新后的Mises应力、等效塑性应变写到一个外部文件。出问题时先看这些中间量,和手算或单点脚本对比,比在后处理里翻半天结果省时得多。这个习惯帮我排掉了至少十个看似莫名其妙的问题。

回弹分析里还有一件事要特别提醒。回弹量的计算依赖于卸载阶段的应力重分布,而卸载路径的准确程度直接由本构积分的切向模量决定。如果切向模量跟加载段一样全是弹性,回弹量自然偏大或偏小。这就是为什么纯等向硬化模型做回弹经常失败,换组合硬化模型就好很多。理解了这一点,你就能明白为什么同一个零件,材料参数多一个背应力演化项,回弹结果能差出一大截。

我个人在实际操作中的体会是,塑性力学算法这种东西,光看书就像隔靴搔痒。把径向返回算法用Python写一遍,再用Fortran塞进UMAT,最后拿单轴拉伸实验对照一次,你才算真正掌握它。后续如果想扩展,可以在J2框架上继续加率相关项模拟高应变率,加损伤变量模拟断裂,甚至从宏观本构往晶体塑性走。但无论走多深,底层那个“弹性预测-塑性校正-切线更新”的骨架都不会变。先把骨架打牢,后面的一切都是添砖加瓦。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询