近两年,收到许多同学关于Abaqus软件使用过程中Fortran子程序调试的问题,在形形色 色的错误面前许多初学者无从下手,不知如何去查找问题所在。本文将对Abaqus中子程序的调试方法以及如何对错误进行预警做一个简单的介绍。
通过总结各类错误问题,大致可以把子程序编写过程中的常见错误归为三类:模型错误、语法错误和逻辑错误。
1、模型错误:
有限元模型中自身材料、截面属性、网格类型、网格划分方式、接触设置、边界/载荷设置、输出设置、软件子程序配置等引起的错误,非子程序本身的错误。此类错误一般会在任务监控界面下的Error或Warning栏中有具体提示。
模型错误属于有限元模型常规建模错误,可以先使用非子程序模型予以测试,排除建模错误之后,再改为子程序计算模型。该类错误属于最容易解决的一类。
2、语法错误:
在使用FORTRAN编写子程序时,使用了非法的语句或者非法的格式,而引起的错误。该类错误会直接在任务监控界面提示Error:Problem during compilation编译出错。如下图所示。
具体的语法错误内容将会显示在与任务名同名的XXX.log文件中,该文件位于Abaqus当前的工作目录,语法错误点及所在行数都有明确的提示。例如,将以下代码中第29行注释掉,第28行的语句被打断,变得不完整,将会有哪些提示信息呢?提示信息又将在哪里显示呢?
使用文本编辑软件(notepad 或UE等)将log文件打开,可以考单提示信息如下,具体的错误类型和错误位置都有明确的提示:
语法错误是许多子程序初学者经常会犯的错误,按照上述方式就可以快速定位错误位置了,至于基本的Fortran语言语法,可以参照响应的语法书。
在排除模型错误之后,应优先解决语法错误,此类错误,直观明了,容易查找,也容易修改。
3、逻辑错误
模型自身没有人为建模错误,子程序语法也没有问题,模型可以调用子程序顺利计算,但计算结果明显异常或者刚一开始计算就跳出,没有明确的错误原因,log文件中也查找不到明确的错误提示。这一类错误,暂归结为逻辑错误。一般是由于公式推导有误、书写笔误、数据格式混乱、分母为0等情况导致。
逻辑错误是子程序编写过程中最常见的一类错误,且十分隐秘,不易察觉,调试起来费时费力。
常见逻辑错误类型有以下几种:
① 个别变量未声明或者声明类型与实际数据类型不一致
② 主程序实参维度与子程序形参维度不一致
③ 分母为0
④ If 判断语句位置不复合正常逻辑
⑤ 无限循环
⑥ 引用位置超出数组自身范围
⑦ 理论公式代码化的过程中编写有误
针对逻辑错误,建议如下:
① 应对措施:从前到后,从主程序到子程序,逐个代码块进行检查
② 检查方式:监控打印疑似有问题的变量
例如,将某些变量打印出来:
print * ,NOEL,dft,dmt,dfc,dmc
!输出多个单变量
print *,stress(1:6)
!输出数组strss
print*,‘F1=’,F1,‘F2=’,F2
!输出变量及提示信息
do ii=1,6
print*,int(C0 (ii,1:6))
end do
!输出6*6矩阵C0
通过print打印出来的数据将显示在Abaqus当前工作目录下与任务名同名的log文件中(或命令提示窗口),根据打印出来的数据信息,逐个检查有问题的数据,进而判断错误在哪里?一般应从前到后,从主程序到子程序,一个代码块一个代码块顺序检查,直至检查到程序最后,所有数据均正常。
打印效果如下:
除了print之外,也通过write命令将数据打印输出到指定文件中,如error.dat,根据打印出来的数据信息,逐个检查有问题的数据,进而判断错误在哪里?
open(unit=10, file=‘error.dat')
! 打开error.dat文件,unit指定文件代码,file指定文件名称。
write(10, *) "hello" ,SDV1 ,X,Y,Z
!在文件中写入hello及多个变量
预警提示
有些情况下,错误是可以预计的,即在某种条件下,数据自然会出现异常,因此,可以提前在可能出现错误的地方给予相应的错误提示信息。例如,下面的公式:
正常情况下,d为正数,因此,当x<=y时,应在程序中给出错误提示信息。在程序执行过程中,如果出现了该类型提示,就可以直接判断出问题出现的位置。
if ( x .le. y) then
print*,"d不是正数,请检查数据"
end if
以上仅为个人经验之谈,欢迎纠错和补充完善。
作者:君莫 仿真秀科普作者
声明:原创文章,首发复合材料力学本文已授权,部分图片源自网络,如有不当请联系我们,欢迎分享,禁止私自转载,转载请联系作者。