ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

单晶塑性UMAT开发指南:核心公式、代码骨架与避坑策略

单晶塑性UMAT开发指南:核心公式、代码骨架与避坑策略 搞UMAT这事圈里人都知道入门不难入门之后全是坑。单晶塑性UMAT更是把晶体学、连续介质力学、有限元数值算法三个山头全踩了一遍。我自己从对着子程序模板发懵到能跑通一个多晶模型的拉伸响应中间折腾了小半年。这篇东西就是把这条自学路线、核心公式、代码骨架、以及我踩过的那些莫名其妙的问题一次性捋清楚给想自己写单晶塑性UMAT的人少走点弯路。先交代清楚这篇文章解决什么问题你有一个想要实现晶体塑性行为的单晶模型可能是为了算滑移系统开动、织构演化也可能是给多晶RVE做准备。在ABAQUS里材料库给不了你这种东西必须靠UMAT自定义本构。它能算的东西很明确给定一个材料点的变形历史返回更新后的应力状态和材料雅可比矩阵让整体隐式求解能收敛。适合谁看有一定ABAQUS基础、读过一点晶体塑性文献、但不知道代码怎么落地的人。我默认你会写一点Fortran不要求精通但起码看得懂主程序结构。下面所有内容都是按“从零手写一个能跑的FCC单晶UMAT”这个目标来组织的。1. 整体设计思路为什么单晶塑性必须自写UMAT1.1 软件自带材料为什么做不了晶体塑性ABAQUS内置材料模型再丰富本质上是宏观唯象模型。它把材料当成一个连续的均匀介质用屈服面、硬化律和流动法则去描述塑性变形。这套框架在处理多晶体材料时用的是平均化和空间分布的思路根本不会去跟踪每一个晶粒内部的滑移系开动情况。但单晶塑性需要的是知道每一个积分点所属晶粒的晶体取向然后根据该取向计算哪些滑移系最容易开动、哪些滑移系的剪切应变累积了多少、晶格旋转到了哪个位置。这些东西在ABAQUS自带材料库里完全没有接口。你就算想改也只能改屈服面参数改不出滑移系分辨率和晶体取向相关性的效果。UMAT存在的意义是让用户把本构关系“插”进ABAQUS的标准求解流程。它接收应变增量、温度增量、状态变量和一些其他求解信息你自己定义应力更新方式和雅可比矩阵DDSDDE。从力学的角度讲你拥有把物理关系写成代码的全部自由。1.2 单晶塑性的核心理论脉络晶体塑性的理论基础拆开看其实就三块第一块是变形梯度分解。晶体的大变形被分解为弹性部分和塑性部分典型的乘法分解形式为 F Fe · Fp。Fe描述晶格的弹性变形和刚体转动Fp描述滑移引起的塑性剪切。分解的前提是塑性变形只沿特定滑移系发生不改变晶格本身的取向至少在中间构型下是这样。第二块是滑移系的定义。FCC晶体有12个{111}110滑移系每个滑移系由滑移面法向和滑移方向定义。你需要用晶体学数据把这12个滑移系的法向量和方向向量都算出来然后按晶体取向旋转到全局坐标系下。第三块是流动法则与硬化律。剪切应变率用幂律给出最常见的形式是[ \dot{\gamma}^\alpha \dot{\gamma}_0 \left( \frac{\tau^\alpha}{g^\alpha} \right)^{1/m} ]其中τ是Schmid应力g是滑移系强度m是率敏感指数。硬化演化可以用Voce硬化也可以用位错密度的演化模型。Voce硬化形式写出来大概是[ \dot{g}^\alpha \sum_\beta h_{\alpha\beta} |\dot{\gamma}^\beta|, \quad h_{\alpha\beta} h_0 [q (1 - q)\delta_{\alpha\beta}] (1 - \frac{g^\beta}{g_\infty})^a ]这套理论框架在文献里很成熟但在UMAT里实现时平滑的幂律会带来高非线性数值处理不当就会出现典型的收敛问题。这是后面要重点讲的内容。1.3 UMAT自学的技术路线全景自学单晶塑性UMAT最容易犯的错误是拿起一本书就从头读或者直接找一篇论文里的本构方程就开写代码。结果往往是理论看懂了代码却不知道怎么组织。我建议的路线是这样第一步搞懂UMAT接口规范和ABAQUS的调用逻辑。知道STATEV、STRESS、DDSDDE、PROPS这些变量分别是什么意思知道每一步增量调用的顺序。这一步别跳。第二步做线性弹性UMAT验证接口通了没有。一个单单元单轴拉伸案例能跑通再谈后面的晶体塑性。第三步加入滑移系运算和剪切应变率先做显式更新验算应力-应变曲线在单个单元上是合理的。第四步再做隐式迭代和一致的雅可比矩阵提升收敛性。第五步做多晶模型加取向分布和文献结果对比。这个路线的核心逻辑是“最小可运行”原则——任何一步都保证有一个能跑的最小验证模型避免到最后全写完才发现错在第一步。2. 核心细节解析晶体取向、滑移系与DDSDDE2.1 滑移系的数据准备与坐标系变换FCC晶体12个滑移系我先把数据给全。{111}面的四个法向加上110方向的三个滑移方向两两组合去掉重复项得到12个滑移系。以标准的Miller指数表述滑移面法向为(1 1 1)、(1 -1 -1)、(-1 1 -1)、(-1 -1 1)滑移方向在110族中选取对每个面取三个可能的110方向要求该方向在该面内。例如对(1 1 1)面滑移方向可以为[1 -1 0]、[0 1 -1]、[-1 0 1]。在输入文件或UMAT中不能直接用Miller指数做运算。你需要把它们化成单位向量。比如[1 -1 0]方向归一化后变成 (1/√2, -1/√2, 0)。滑移面的单位法向同理处理。这里有一个特别关键的细节ABAQUS中材料的默认取向是所有材料坐标轴与全局坐标轴重合。如果你的晶体方位角用了Euler角Bunge约定最常见你必须在UMAT里做两次变换。第一次是把滑移系从晶体坐标系转到材料坐标系第二次是把材料坐标系转到全局坐标系。材料取向信息在UMAT中可以通过COORDS和CMNAME判断或用*ORIENTATION配合用户子程序ORIENT参数传递方向余弦矩阵。但更简单的做法是在输入数据PROPS里直接给欧拉角在UMAT初始化时算好方向余弦矩阵把晶体坐标下的滑移系预先旋转到全局坐标。这样每次迭代就不用反复做矩阵乘法能省不少CPU时间。2.2 流动法则与剪切应变率的数值处理理论公式里剪切应变率与Schmid应力呈幂律关系好处是光滑连续没有切换问题坏处是当率敏感指数m比较小比如m0.01函数非常刚硬一个微小的应力扰动会导致剪切应变率产生巨大变化。在静力隐式求解中这种高非线性会让全局牛顿迭代频繁发散。一个常用的处理手段是引入粘塑性正则化不追求严格率无关而是允许一点率相关让求解器有喘息空间。实际操作中我会以小规模试算把m设为0.05左右先跑通再说。如果文献里的材料确实是低率敏感的再逐步把m调小同时缩小增量步。这个参数你不用一开始就对先用一个能收敛的值。数值上最重要的一个细节是在增量步内剪切应变增量Δγ需要通过迭代求解。简单地把当前的Schmid应力带进去算一个率然后乘以ΔT属于显式前推收敛性较差。更好的做法是采用后退欧拉法在增量步结束时让自己一致[ \Delta\gamma^\alpha \Delta t \cdot \dot{\gamma}0 \left( \frac{\tau^\alpha{\rm trial} - \sum_\beta C_{\alpha\beta} \Delta\gamma^\beta}{g^\alpha} \right)^{1/m} ]这个方程要解一个非线性方程组滑移系数量越多越麻烦。FCC的12个滑移系还好用牛顿迭代可以实现如果后面要做HCP、BCC的多滑移系要小心处理。提示在实现过程中先实现“每个滑移系独立求解、硬化耦合”的格式不要一上来就搞全耦合牛顿迭代。独立求解的代码简单能快速验证基本行为确认了原理再升级成全耦合版本。2.3 DDSDDE雅可比矩阵弹性切线、一致切线还是近似切线DDSDDE这个矩阵是ABAQUS进行牛顿迭代时用到的切线刚度。理论上它越接近真实的一致切线矩阵收敛速度越快。但工程上很多能跑的UMAT只是给了个弹性切线或简单弹塑性切线照样能用只是收敛需要的迭代步数多一点。对晶体塑性来说严格推导一致切线矩阵需要把本构关系对总应变求偏导涉及 12x12 滑移系方程组的求逆。这个推导过程费时间而且容易出错。我的经验是先写一个近似的弹性切线让整体程序先跑起来再根据收敛情况决定要不要升级成一致切线。近似的DDSDDE可以直接用弹性矩阵C。这样做每个增量步里应力的更新仍是晶体塑性计算结果只是切线的方向有点“粗糙”。对高度非线性问题这样做收敛慢但稳定。等到你的模型在单晶单轴拉伸下能跑出合理曲线再回头把一致切线做出来会容易得多因为你能用数值差分去验证解析推导是否正确。一个小技巧用一个很小的应变扰动重新调用本构更新对比DDSDDE数值和解析值差异过大就说明推导有误。2.4 晶格旋转问题要不要算什么时候可以忽略单晶塑性的大变形中晶格旋转不可忽视。随着塑性剪切进行滑移方向会旋转Schmid因子会改变应力状态会出现明显的各向异性响应。这一效应在加工过程模拟如轧制、锻造、挤压中尤其重要。在UMAT中实现晶格旋转需要在每个增量步更新滑移系的方向。做法是从变形梯度中提取弹性部分Fe对Fe做极分解得到旋转矩阵R再用R去旋转滑移系法向和方向。这一步如果在代码中遗漏小变形没问题大变形计算结果就完全不对。如果你前期只是做小变形验证可以不更新晶格取向把Fe近似为单位张量或只做小旋转处理。但正式做工程模拟前这段逻辑是必须补上的。3. 实操过程从零搭建单晶塑性UMAT骨架3.1 UMAT主程序框架解析我先给出一个能运行的FCC单晶UMAT的骨架这是“最小版本”。在这个版本里我用了简单的显式更新弹性切线目的是让你快速跑通接口验证晶体塑性行为的基本特征。SUBROUTINE UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD, 1 RPL,DDSDDT,DRPLDE,DRPLDT, 2 STRAN,DSTRAN,TIME,DTIME,TEMP,DTEMP,PREDEF,DPRED, 3 CMNAME,NDI,NSHR,NTENS,NSTATV,PROPS,NPROPS,COORDS, 4 DROT,PNEWDT,CELENT,DFGRD0,DFGRD1,NOEL,NPT,LAYER, 5 KSPT,KSTEP,KINC) C INCLUDE ABA_PARAM.INC C CHARACTER*80 CMNAME DIMENSION STRESS(NTENS),STATEV(NSTATV),DDSDDE(NTENS,NTENS), 1 DSTRAN(NTENS),TIME(2),PROPS(NPROPS),COORDS(3), 2 DROT(3,3),DFGRD0(3,3),DFGRD1(3,3) C C 材料参数PROPS(1): 弹性模量E C PROPS(2): 泊松比NU C PROPS(3): 参考剪切应变率gamma0_dot C PROPS(4): 率敏感指数m C PROPS(5): 初始滑移系强度g0 C PROPS(6): Voce硬化饱和强度g_sat C PROPS(7): 硬化模量h0 C PROPS(8): 硬化指数a C PROPS(9)~PROPS(11): 欧拉角(角度制) C C 状态变量STATEV(1~12): 各滑移系剪切应变累计 C STATEV(13~24): 各滑移系当前强度 ...UMAT的主流程分为四步。第一步是初始化读取PROPS并计算弹性刚度矩阵如果是从初始增量开始还要初始化滑移系方向。第二步是更新弹性预测应力先假定整个增量都是弹性变形用弹性刚度矩阵和应变增量计算出预测应力。第三步是塑性修正基于当前应力计算Schmid应力根据流动法则计算各滑移系的剪切增量修正应力值。第四步是输出更新状态变量填入DDSDDE和STRESS。在真实代码里第三步最大的坑是Schmid应力的计算。Schmid应力等于滑移方向的单位向量与应力张量点乘再与滑移面法向点乘即[ \tau^\alpha \sigma : (m^\alpha \otimes n^\alpha) ]在代码里要小心张量缩并的次序。很多初学者在这里写错索引导致结果完全对不上查半天发现是Fortran数组下标顺序问题。3.2 单单元拉伸验证正确的自学调试姿势UMAT写完后第一个要跑的测试模型永远是单单元拉伸。不要直接上去跑多晶模型。单单元的好处是能快速验证本构行为排除网格和边界条件的干扰。模型怎么建在ABAQUS CAE里创建一个C3D8R六面体单元材料参数对应你的UMAT。边界条件是一端约束另一端给一个位移或速度模拟单向拉伸。如果你启用了hourglass控制C3D8R可以工作但更稳妥是先用C3D8避免沙漏影响判断。跑完后提取工程应力-应变曲线重点看三条特征第一初始弹性段斜率是否和输入弹性模量一致。如果不一致说明弹性矩阵组装或应力映射有问题。第二屈服点出现的位置。单晶的初始屈服与Schmid因子有关。比如FCC单晶沿[001]方向拉伸多个滑移系对称开动初始屈服应力约为g0除以最大Schmid因子约0.408所以屈服应力大概是2.45倍的g0。如果曲线在明显偏早或偏晚的地方屈服说明滑移系方向矩阵或应力计算方法有误。第三硬化段趋势是否平滑。通过改变硬化参数看曲线斜率是否对应变化。这能帮你判断Voce硬化实现是否正确。3.3 从单晶到多晶Voronoi与cohesive晶界模型的接入单晶UMAT跑通后最常见的扩展方向是构建多晶模型用于研究晶界、织构、多晶塑性响应。这里经常用到两个关键词Voronoi和cohesive。Voronoi图用来生成多晶的晶粒几何。在ABAQUS中可通过脚本或第三方工具生成Voronoi多边形/多面体然后把每个晶粒分配不同的晶体取向给每个晶粒内部的积分点赋上对应的欧拉角。这里的关键是“每个积分点都要知道自己是哪个晶粒的”通常通过给每个晶粒单独赋予材料方向或材料属性实现。cohesive则用来模拟晶界行为。如果要研究晶界滑移或晶界开裂可以在Voronoi晶粒之间插入cohesive单元赋予双线性牵引-分离本构。这一套可以做晶间断裂分析。但它和UMAT的关系是UMAT管晶粒内部变形cohesive管晶界失效两者在同一个模型中耦合。一个常见坑cohesive单元和UMAT的积分点并不共享同一个材料模型。你需要在两部分分别赋材料属性。这样调试时晶粒内部先用弹性材料或简单弹塑性材料等cohesive晶界特性验证完毕再把UMAT接进去。叠加调试能省大量时间。4. 常见问题与排查技巧实录4.1 UMAT收敛问题的系统排查顺序UMAT最常见的失败表现是“too many attempts made for this increment”也就是增量步怎么减都算不过去。我的排查顺序如下第一检查DDSDDE是否异常。先临时把DDSDDE设成弹性矩阵如果原本发散的问题解决了说明材料切线矩阵有问题可能存在负的主特征值或者方向搞错。第二降低加载速率。晶体塑性幂律对应变率异常敏感如果加载速度过高局部应变率远超参考值剪切应力会飙到非物理的程度。把加载速度降一个数量级收敛性通常立竿见影。第三打开粘塑性正则化。给流动法则加一个微小的时间相关项或者把m暂时增大如从0.01调到0.05能极大改善收敛。这不是作弊而是标准做法在极低速加载条件下结果几乎不变。第四细看状态变量。用ABAQUS后处理查看STATEV分布看是否出现个别积分点状态变量突变。常见原因是单元畸变或局部大变形导致滑移系方向矩阵更新失效可以在该处加密网格或加hourglass控制。第五检查单位制。这个错误发生频率极高。ABAQUS不强制单位制但如果你用mm-N-s的体系去配UMAT里的密度和质量所有结果都会量级错乱。单晶塑性研究中应力用MPa长度用mm时间用s整套一致传递。4.2 libpng error与常见的运行环境问题运行环境问题往往是新手浪费时间的重灾区但和本构知识没任何关系。ABAQUS报libpng error这个词在最近的热搜里出现很多。多数情况是软件在读取或写入PNG图像时库版本不兼容或显卡驱动解析异常。通常发生在后处理保存图片、导出动画、或界面刷新时。排查方法很简单第一步重启ABAQUS第二步检查是否用了非ASCII路径比如中文目录libpng在某些版本对路径编码敏感改成纯英文路径第三步更新显卡驱动。如果还不行尝试在“Graphics Preferences”中关闭硬件加速。“abaqus中断不了怎么办”当你发了STOP或CtrlC后job仍然不终止。最常见的原因是用户子程序在某些数值迭代里卡死或并行求解的进程没有收到终止信号。建议不要反复点界面上的取消直接用系统任务管理器结束standard或explicit进程。如果用的是命令行提交的job找到对应的PID强制kill掉。更彻底的排查是如果子程序里有严重死循环或等待锁要先修复代码再重跑否则每次中断都会卡。“abaqus使用gpu加速”很多新版Abaqus支持GPU加速但这不是对任何分析都有效。UMAT用户子程序运行在CPU上GPU主要加速线性代数和单元组装部分。如果你的模型规模不大GPU带来的收益有限。强行追求GPU加速反而可能因为显存不足导致OOM或者求解器异常退出。实用建议先用CPU多线程把模型跑通再评估是否值得花时间配置GPU。4.3 晶粒多晶模型中的网格与单元建议多晶模型里单元选择非常影响收敛和结果质量。C3D8R减缩积分单元在弯曲和剪切问题里容易沙漏尤其在晶粒边界附近应力梯度大时。解决办法是加enhanced hourglass control或者直接换C3D8。C3D8没有沙漏问题但在弯曲主导的问题里偏刚多晶塑性下最好配合足够的网格密度。对Voronoi多晶模型晶粒间是平面边界网格要尽量贴合晶界。否则在晶界处的单元会横跨两个晶体取向导致积分点的材料方向取值不连续数值上出现“伪边界”。这个在生成网格时要严格处理让单元边与晶界重合。注意多晶模型里如果每个晶粒的材料方向通过*ORIENTATION赋给要确保每个晶粒的区域编号和方向定义一致。一个常见的低级错误是多个晶粒共享同一个方向结果算出来和单晶无异白白浪费计算资源。4.4 cohesion与Voronoi联合仿真时的参数匹配当你在Voronoi晶粒间插入cohesive单元时需要注意两个参数体系的匹配晶粒内部的UMAT强度参数和cohesive的牵引-分离参数。如果UMAT的量级是MPacohesive的最大牵引应力也必须用MPa。如果一方用了N/m²另一方用了N/mm²界面强度会和晶粒强度差几个数量级宏观响应完全失真。判断匹配是否合理可以做一个简化的三点弯曲或双悬臂梁测试单独拉出晶界的cohesive单元看失效行为不要在完整多晶模型中直接调参。因为多晶模型中应力集中分布于晶界附近很难分清是哪一侧的参数导致的失效。5. 避坑指南参数标定、单双精度与调试技巧5.1 材料参数从哪里来单晶塑性UMAT做出来的结果只有和实验或文献数据对了才算数。FCC金属如铜、铝、镍基合金的单晶弹性常数是现成的比如铜的C11168.4GPa、C12121.4GPa、C4475.4GPa。你可以用各向异性弹性矩阵替代最简单的E和nu结果会好很多。硬化参数则需要通过拟合单晶应力-应变曲线获得。如果你没有单晶实验数据可以先从多晶拉伸实验反推先假设潜硬化和自硬化相同q1用简单的Voce硬化拟合多晶拉伸响应再回头校核单晶响应。一个大坑单晶塑性对欧拉角极其敏感。即使是纯单晶“[001]方向拉伸”这种说法实际中如果晶体取向偏了哪怕2度屈服强度和后期的硬化响应都会有明显差异。建立模型时给出的欧拉角要和自己用的转动约定保持严格一致。Bunge、Kocks、Roe三种约定下同一个欧拉角表示的是完全不同的取向千万别搞混。5.2 单精度和双精度的选择ABAQUS exaction默认可能用单精度或双精度这取决于安装版本和分析类型。对单晶塑性UMAT来说强烈建议使用双精度。原因在于晶体塑性本构里剪应力在滑移系之间的微小差异会对结果产生决定性影响。单精度下应力值在小数点后几位被截断可能导致对称滑移系的剪切应变分配出现数值不对称出现伪各向异性。在Abaqus Command里提交job时记得加doubleboth选项或者用CAE中的“Precision”设置。同时在UMAT的Fortran代码中变量声明也要注意隐式类型所有用到浮点数的变量不要和整型混用否则精度损失在程序内部就已经发生了。5.3 增量步和最大迭代次数怎么设置UMAT写完后Abaqus/Standard中默认的增量步设置通常不能满足晶体塑性的收敛需求。实践经验是初始增量步设成总时间的0.01最小增量步设成总时间的1e-6或更小最大增量步设成总时间的0.05。这样做的好处是前几个增量步不会因为应力突变而反复回退。如果你发现输出结果在屈服点附近振荡把初始增量步再减小一个量级。在求解控制里可以适当增加每个增量步允许的迭代次数上限Iterations to Attempt。默认值有时是8次晶体塑性可能要到15~30次。增加迭代上限比无限减小增量步更高效至少能让你的调试过程少一点挫败感。5.4 数值差分验证与状态变量检查UMAT调试过程中有一个技巧非常值得掌握数值差分验证DDSDDE。在ABAQUS外部或用一个简单的Fortran测试程序调用相同的本构更新逻辑给定一个微小扰动δ给某个应变分量对比应力的数值差分和DDSDDE对应的列两者一致才能说明雅可比矩阵是对的。这个方法虽然朴素但能抓出90%以上的矩阵实现错误。状态变量的检查和记录同样重要。写好UMAT后第一时间把每个滑移系的累计剪切应变和当前强度输出到后处理。观察这个分布是否与物理直觉一致比如单晶拉伸时对称滑移系的剪切应变应该相等。如果不相等说明滑移系编号、符号约定或方向余弦矩阵有问题。6. 最后的几句实在话UMAT这条路说到底是个反复试错的过程。我见过很多人卡在最开始的一步对着代码找不到入口不知道从哪一行开始读。我的建议是别从别人的完整代码开始读那只会让你更晕。你只需要一个最小框架加一个最简单的线性弹性更新先跑通再逐步叠加晶体塑性的理论细节。每叠加一步就跑一个单单元验证确认没问题了再走下一步。晶体塑性的理论书很多文献也很多但能把公式变成能收敛的UMAT翻来覆去就是那几步滑移系方向、Schmid应力、剪切应变率、硬化更新、应力修正。这个闭环一旦通了后面的扩展就只是增加复杂度而已。我自己踩过的坑还包括在输出变量时把所有状态变量都写出来结果在超大模型里后处理文件膨胀得无法打开还有一次在Fortran里没加IMPLICIT NONE隐藏的变量类型错误让我在两个星期里反复怀疑本构公式写错最后才发现是一个普通的拼写错误。所以动手之前先做好代码卫生能帮你省下难以计数的排错时间。如果你正准备开始我的最后建议是第一天先不要碰晶体塑性理论先花一个晚上把线性弹性UMAT接口跑通第二天再开始加滑移系。这一步看着简单却能拦住超过一半的自学者。跨过去了后面的事就是时间和耐心的问题了。
返回列表