DLOAD和UMAT同时要用的模型,提交完卡在编译那步,报了一堆“unresolved external symbol”,翻了半天发现两个子程序写在两个.f文件里,ABAQUS根本不认。
同一个模型里要同时用多个子程序,唯一硬性规则就是所有子程序必须写在同一个.f或.F文件里,ABAQUS只接受一个用户子程序文件。D:\temp\multi_sub\all_subs.for,里面UMAT、DFLUX、DLOAD排着放,顺序无所谓,别一个文件一个subroutine就行。CAE里Job模块 → Edit Job → General → User subroutine file,选这个合并后的文件,或者命令行abaqus job=Job-1 user=D:\temp\multi_sub\all_subs.for cpus=4 interactive。每个子程序函数体里该加的INCLUDE 'ABA_PARAM.INC'一个都不能少,这行包含了编译链接需要的关键参数,漏了任何一个都会报编译错误。
子程序之间如果需要共享变量,用Fortran Module。在文件开头定义module mod_share,里面声明共享变量,比如real(8):: force1,每个子程序里use mod_share,UMAT把计算出来的值写进去,DFLUX读出来用,同一Module在多子程序间共享变量。Common块也能干这事但现代Fortran不推荐了,Module清晰得多。多个子程序之间ABAQUS不允许直接互相调用,想调用只能通过Module共享数据或者主程序接口传参。

有一次给一个焊接模型同时挂DFLUX和UMAT,DFLUX负责移动热源,UMAT负责焊缝区材料的相变塑性。两个子程序单独跑都没问题,合到一个文件里编译过了,但一提交就报“CMNAME has not been initialized”。当时是晚上加班,外面走廊灯都关了,就我工位这盏亮着,空调出风口对着吹,冻得手有点僵。查了半天发现UMAT里用了CMNAME判断材料类型,DFLUX里没定义CMNAME这个变量,编译能过但运行时读不到值。在DFLUX里加了一行CMNAME='DUMMY'之后好了。后来又发现DFLUX往ODB里写SDV的时候跟UMAT的SDV编号撞了,UMAT的SDV1是损伤,DFLUX的SDV1是温度场,后处理的时候看损伤云图全是温度值,调了半天才发现编号重叠,把DFLUX的SDV往后挪了20个编号才错开。
多材料用同一个UMAT的时候靠CMNAME分支,一个UMAT里用IF判断CMNAME的前四个字符,'MAT1'走一套本构,'MAT2'走另一套。每个分支里建议再拆成独立的子函数,主UMAT只负责转发,比如IF(CMNAME(1:4).EQ.'MAT1') THEN CALL UMAT_MAT1(...),'MAT2'的时候CALL UMAT_MAT2(...),这样代码可读性好,改其中一个不影响另一个。UEL里对应的变量是UTYPE,用法跟CMNAME类似。
编译器关联这块,Abaqus 2025之后Intel oneAPI把ifort换成了ifx,需要在win86_64.env里把ifort改成ifx,文件在SIMULIA\EstProducts\2025\win_b64\SMA\site目录下。abq2025.bat里加一行call "D:\Program Files\Intel\oneAPI\setvars.bat" 1>nul,运行ABAQUS前先初始化Fortran环境,末尾的1>nul把setvars的输出屏蔽掉,不影响计算只让启动界面干净些。VS不是默认C盘的话要设VS安装路径的环境变量,不然setvars.bat找不到。
有一次同事的模型同时挂了UMAT和UEL,迁移到新机器上怎么都编不过,一直报“LNK2005: already defined”。那个同事平时用的是Abaqus 2021 + VS2019 + IVF2020的经典组合,新机器装的是VS2026 + Intel Fortran Compiler 2025,单独跑UMAT没问题,加上UEL就崩。把abq2021.bat里调用的编译器从ifort改成ifx重新试,链接错误消了但算到一半结果明显不对,UEL的刚度矩阵量级差了十几个数量级。最后换回ifort配合VS2019才跑通。版本兼容这事没有通用解,能用经典组合就别乱升。
后处理调试多子程序的时候,write(*,*)往屏幕打的输出在Explicit里不显示,Standard里偶尔能刷出来但不稳定,靠谱的做法是把中间变量存到SDV里,后处理用ABQ_STATE读出来。多个子程序如果都要往SDV里写,编号区间提前规划好,别重叠。调试阶段把Frequency设高一点,每一步都写,跑通了再降下来。D:\temp\multi_sub\all_subs.for,*DEPVAR,NSTATEV=40,
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删