目前,对于材料力学行为的研究,ABAQUS UMAT技术几乎成了标配。只要涉及强度预测、失效准则、蠕变、粘弹性、疲劳、应变率效应、固化变形等等研究,大家的论文中如果没有本构的讨论、UMAT或者VUMAT的内容,就会显得文章没有深度。即便是用其他的商用软件,也会涉及到自定义本构的问题。UMAT之于ABAQUS,就像UDF之于Fluent。

国内大规模搞这些子程序研究有20多年了,我个人接触这个东西也有10年。最初接触它,总觉得它神秘又高端。后面用的多了,又觉得无非是在现有程序基础上改改参数或者加点模型。随着自己开发有限元软件,又发现如何给用户开放自定义本构权限,实际上是软件架构设计的一个难点。本文更想讨论的是,UMAT为什么是今天看到的这个样子,以及未来有哪些可能性。
什么是UMAT
UAMT程序结构
如何编写UAMT
如何调用UAMT
如何调试UAMT
如何配置子程序
未来设想
什么是UMAT
UMAT:User-defined mechanical material。顾名思义,就是用户自己定义材料力学行为的子程序。一般而言,就是定义材料的应力应变关系,即本构。最初接触它的时候,有一点畏难心理,感觉这个不好学,而且麻烦。原因主要有:
(1)准备工作复杂。需要安装适合版本的Fotran、VS,且有安装顺序。然后和ABAQUS关联。稍有不慎,就得重装。
(2)编程问题。现在本科大部分都不再教授Fotran,尽管这个语言并不难学。
(3)力学基础。需要具有弹性力学、有限元基础,了解增量法和全量法的编程流程。
现在回过头看,由于以上三点原因,导致我在初学的时候一头扎进这些问题里面,在很久以后再意识到。UMAT本质上是子程序,什么是子程序?就是可以被主程序调用的一个函数。比如我们在Python中def自定义的函数,比如在Matlab中定义的function。当我明白了这一点,以前学习UMAT的困惑也都迎刃而解了。比如ABAQUS的子程序之所以是Fotran语言,除了Fotran本身计算效率高的原因外,很大程度上是因为ABAQUS本身的求解器也是用该语言编写的。
我们自己在研的求解器和有限元软件使用Python编写的,未来我们开放子程序权限的时候,也肯定是用Python语言了。
回到本构。举例,最简单的一维线弹性(弹簧)本构:
F=K·x
我们就可以在UAMT中描述这个关系,当然是采用矩阵进行描述,告诉求解器应力和应变之间的关系,这样求解器在求解的过程中就会按照我们描述的关系来进行力学模拟。如果根据某个条件,判断出材料在某个应力状态时,刚度发生了变化,在程序中加一个if语句,对弹性参数做修改即可。
因为有这样的特点,所以UMAT是我们研究复合材料力学行为最常用的手段之一。比如所谓的损伤折减研究,就是在迭代过程中,根据材料的应力状态判断损伤的发生,然后对其刚度性能做出相应的折减。因此UMAT是嵌入在求解器迭代中使用的。
对应的有限元求解器基本步骤
1. 组建刚度矩阵K,abaqus自己处理
2. 载荷列阵F,abaqus自己处理
3. x=K^-1*F,所有节点的位移 abaqus自己处理
4. 根据x,求每个单元的应变增量值 abaqus自己处理
5. 根据单元应变和单元刚度矩阵,求应力。UMAT处理
UMAT在迭代中发挥作用
F, F/10(总载荷和载荷增量)
Step1 F/10,stran0=0,Dstran1,stran1=stran0+Dstran1→UAMT计算stress1
Step2 F/10,F/10,stran1,Dstran2,stran2=stran1+Dstran2→UAMT计算stress2
......
UAMT程序结构
UMAT子程序的结构可以分为三个部分:
头部。用来定义变量和变量大小,见下面的标黄区域。
正文。描述本构关系 。
结束,见下面红色字体。
子程序基于Fortran语言编写,形式如下:
SUBROUTINE UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD,
1 RPL,DDSDDT,DRPLDE,DRPLDT,
2 STRAN,DSTRAN,TIME,DTIME,TEMP,DTEMP,PREDEF,DPRED,CMNAME,
3 NDI,NSHR,NTENS,NSTATV,PROPS,NPROPS,COORDS,DROT,PNEWDT,
4 CELENT,DFGRD0,DFGRD1,NOEL,NPT,LAYER,KSPT,KSTEP,KINC) !子程序的变量
C
INCLUDE 'ABA_PARAM.INC' !include 语句为浮点变量设置了适当的精度
C
CHARACTER*80 CMNAME !定义材料名称最多占用的字符位数
DIMENSIONSTRESS(NTENS),STATEV(NSTATV),
1 DDSDDE(NTENS,NTENS),DDSDDT(NTENS),DRPLDE(NTENS),
2 STRAN(NTENS),DSTRAN(NTENS),TIME(2),PREDEF(1),DPRED(1),
3 PROPS(NPROPS),COORDS(3),DROT(3,3),DFGRD0(3,3),DFGRD1(3,3),
4 DSTRES(NTENS) !定义变量的大小
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.....................................代码正文,定义应力应变关系
C!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RETURN
END
比较重要的两个部分是子程序变量、变量大小的定义。有过其他代码编写经验的话,特别是写过自定义的函数代码可以理解为:
SUBROUTINE UMAT是函数名称,后面括号跟的是函数输入。
变量大小的定义是注释性的设置,表明每个变量的数组大小。
下面一个重要的问题来了,既然子程序实质上是一个自定义的function,即有着固定的传入参数和返回参数。UMAT的返回值是那些呢?我们看官方文档:
The following quantities must bedefined:Stress(STRESS), SDVs(STATEV), and material Jacobian(DDSDDE)
The following variables may bedefined: Strain energy(SSE), plastic dissipation(SPD), and “creep” dissipation Suggested new (reduced) time increment(SCD)
从文档中可以看出,UMAT的返回值分为两类:
必须要计算的:STRESS、STATEV(如果定义了SDV)、DDSDDE;
按需返回的:SSE、SPD、SCD。
也就是说,在程序的正文部分,STRESS、STATEV(如果定义了SDV)、DDSDDE一定要更新。
上面我们看到那么多眼花缭乱的变量,这些变量具体是干啥的呢?看下面的表格,灰色的区域是重要常用的变量。
STRESS(NTENS) | 该增量步开始之前的应力向量,在增量步结束之后,必须进行更新。如果指定了初始应力,则该向量在分析开始始将保持初始应力。真实Cauchy应力。 | 需要定义的变量,在所有分析情况下均适用。 |
STATEV(NSTATV) | 求解过程中的状态变量的存贮向量。在该增量步开始时,用来传递状态变量,除非进行了更新(采用USDEFL或UEXPAN)。在增量步结束时,STATEV更新为结束时刻的状态变量值。STATEV的维数(NSTATV)由*DEPVAR决定。 | |
DDSDDE(NTENS,NTENS) | Jacobian矩阵,即本构关系矩阵。әσ/әε。除非声明采用非对称方程求解,否则均为对称矩阵DDSDDE(i, j)。 | |
SSE、SPD、SCD | 弹性应变能、塑性耗能、徐(蠕)变耗能。在该增量步结束时进行更新,并在下一增量步开始时进行传递。这些能量参数对于求解结果不起作用,除非结果采用能量形式输出。 | |
RPL | 该增量步结束时,由于材料的力学作工而产生的体积发热量。 | 只用于完全耦合的温度-应力分析 |
DDSDDT(NTENS) | 与温度想对应的应力增量的变化量 | |
DRPLDE(NTENS) | 与应变增量相对应的体积发热量(RPL)的变化量 | |
DRPLDT(NTENS) | 与温度相对应的体积发热量(RPL)的变化量 | |
STRAIN(NTENS) | 该增量步开始之前的总应变向量。如果考虑了热膨胀效应,那么STRAIN仅为力学应变(即已经在总应变中减去了热膨胀得到的温度应变)。这些应变在输出结果中以“弹性”应变给出。 | 信息传递变量 |
DSTRAIN(NTENS) | 应变增量向量。如果考虑了热膨胀应变,则仅表示力学应变增量。 | |
TIME(1) TIME(2) | 当前分析步开始时刻的,时间步的值。 当前分析步开始时刻的,总时间的值。 | |
DTIME | 该增量步的时间增量 | |
TEMP | 当前增量步开始时刻的温度 | |
DTEMP | 该增量步的温度增量 | |
PREDEF | 在当前增量步开始时刻的,预定义的场变量(基于读入的节点值)的内插值向量。 | |
DPRED | 预定义的场变量的增量向量 | |
CMNAME | 用户定义的材料名。由于ABAQUS内部的一些给定材料是以“ABQ_”作为材料名,因此应尽量不采用“ABQ_”作为CMNAME的名称。 | |
NDI | 该点的直接应力分量的个数 | |
NSHR | 该点的工程剪应力分量的个数 | |
NTENS | 应力或应变向量的维数,等于NDI +NSHR。 | |
NSTATV | 求解过程中的状态变量的个数,与材料类型匹配。 | |
PROPS(NPROPS) | 用户定义的材料常数 | |
NPROPS | 用户定义的材料常数的个数 | |
COORDS | 该点的坐标向量。如果在当前分析步中没有考虑几何非线性,COORDS就等于当前坐标系下的向量。否则,COORDS为最开始的坐标向量 | 信息传递变量 |
DROT(3,3) | 转角增量矩阵。代表了刚体的基本坐标系中的转角增量(该基本坐标系就是应力、应变向量存储时的坐标系)。用于用户定义子程序中的向量或矢量状态变量的转角处理,而应力及应变向量在UMAT调用之前已经进行了转角处理。在小位移分析中,该矩阵是一个单位矩阵;在大位移分析中,如果该材料点的基本坐标系随着材料坐标系转动(如壳单元或采用了局部转角坐标时),该矩阵亦是一个单位矩阵。 | |
PNEWDT | 建议的新时间增量与原时间增量(DTIME)之间的比值大小。该变量允许用户在ABAQUS/Standard中输入自动时间增量的计算法则(如果设置了自动时间增量)。对于ABAQUS/Standard的准静态分析中的自动时间增量(基于标准蠕变率积分技术),不允许在UMAT中控制。 在每一次调用UMAT前,PNEWDT被设置为一个足够大的值。 如果没有选择自动时间增量方法,大于1.0的PNEWDT值将被忽略,而起作用的仅是当小于1.0的PNEWDT值时。 | 能够更新的变量 |
CELENT | 特征单元长度。 | 信息传递变量 |
DFGRD0(3,3) | 该增量步开始时刻的变形梯度向量。 | |
DFGRD1(3,3) | 该增量步结束时刻的变形梯度向量。如果在分析步中未考虑几何非线性,则该向量为零。 | |
NOEL | 单元的个数 | |
NPT | 积分点的个数 | 信息传递变量 |
LAYER | 层的个数(用于复合材料的壳单元,及层结构固体单元) | |
KSPT | 当前层的截面点的个数 | |
KSTEP | 分析步的个数 | |
KINC | 增量步的个数 |
如何编写UAMT
Fortran基础
我们在UAMT中常用的语法有:
判断语句
IF ((STRESS(1) .GE. 0) .AND. (mod1 .GE. 1)) THEN
STATEV(1)= 1 !纤维拉伸失效
ELSEIF ((STRESS(1) .LT. 0) .AND. (mod2 .GE. 1)) THEN
STATEV(2) = 1 !纤维压缩失效
END IF
循环语句
DO I = 1, NTENS
STRANT(I) = STRAN(I) + DSTRAN(I)
END DO
比较语法
.GT. 大于(>)
.LT. 小于(<)
.EQ. 等于(==)
还有
.GE. 大于等于(>=)
.LE. 小于等于(<=)
.NE. 不等于(!=)
特殊运算
a的平方:a**2
自然常数的2次方:EXP(2)
自然对数是 log(x)
十为第的对数是 log10(x)
注释
在任意位置使用 ! 可以进行注释
在每行的第一个字符位,用 C 也可以注释
自定义数组变量
在头部的DIMENSION后可以自行定义自己需要的数组变量名称和对应的大小
DIMENSION STRANT(6)
DIMENSION CFULL(6,6),CDFULL(6,6),A(3,3),V(3,3)
自定义常数
可以按照如下形式,自己定义一些常数。
PARAMETER (ZERO = 0.D0,ONE = 1.D0,TWO = 2.D0, HALF = 0.5D0)
如何调用UAMT
调用UAMT需要如下几个步骤:
参数定义部分。
Step设置部分。
Job设置部分。
在参数定义模块,>General,定义变量数目,可以多给但是不能少。>General>User Material,随便给个数,我们在UMAT里面已经定义好参数值了,此处输入的值不会被调用。(下面的图只是示意)

为了能让损伤结果顺利显示,需要在Step>Field Output>State>SDV勾选。(下面的图只是示意)
最后的调用,在Job模块,调用子程序。
损伤通过SDV查看。
如何调试UAMT
提交计算后,如果子程序本身有语法错误,软件会自动终止计算。并在安装路径专门存储计算文件的文件夹下面,生成一个当前工况的.log文件,里面会提升错误代码的位置和信息。根据这些信息我们可以进行代码修改。
除此之外,我们可以在Fortan将关注的变量值实时打印到文件中,帮助我们进行问题定位。
如何配置子程序
前面说了,UMAT本质是子程序,它实际上是需要能够在ABAQUS传入参数后,然后它完成计算再将指定变量返回。我们在一台干净电脑上是无法直接运行C语言代码、MATLAB代码或者Python代码,因为我们没有安装它们的运行环境。这就是UMAT需要做环境配置的原因。
子程序的使用,需要安装VS和FORTRAN,并且将ABAQUS与两者进行关联,才能运行。不同ABAQUS版本可能需要的VS和FORTRAN版本还有区别。这个网上有文件教程可以参考。
https://wenku.baidu.com/view/5766f34dd35abe23482fb4daa58da0116d171f2a.html
嫌麻烦的话,花个几十块找人装。
未来设想
前面提到,未来我们会在自己的有限元软件中也提供自定义接口。这个接口大概率是用Python,当然这个不是重点。
重点是AI快速发展的当下,不少软件都打出了AI赋能的噱头,具体问AI赋能了什么,又都说不清楚,最基础的求解器目前仍然需要依赖稳定精准的数值算法。可以说无论AI如何发展,数值求解器仍然是不可替代的,甚至求解器自身就是AI工具的基础。
那么AI在有限元中比较能发挥作用的地方在哪呢?我们目前的设想是,应该优先在本构模型中发挥作用。即,通过用户描述材料的力学行为特征,AI就可以自动生成UMAT或者VUMAT子程序,供用户使用。
当然,除了AI自身增强对力学概念的理解,还需要数据支持。无论是各种弹塑性模型还是复合材料渐进失效模型,里面各种系数实际上是需要针对不同的材料做试验测试才能获取。尤其是多种多样的复合材料。就我所了解,德国就有将各个试验室和研究单位的材料本构数据统一管理的计划,一旦把数据格式统一,随着时间积累形成大数据库。在AI技术的加持下,说不定靠写材料本构就能研究生毕业的情况,将一去不复返。与之相对的,做基础试验或者寻找材料特性应用场景或将更加重要。
欢迎关注“静界有限元”
工作室面向在校学生、科研院所老师提供结构有限元仿真(含二次开发)、流体力学仿真、算法开发、软件开发服务。