本文介绍abaqus用户子程序中常用到的一些Fortran95语句,这些语句基本可以帮助用户完成大部分基础子程序的编写。以vumat为例,通过VS编写Fortran子程序代码,在abaqus6.14中运行。本文在vumat中介绍各种常用Fortran语句,对于vumat基础感兴趣的读者可以参考:
在使用vumat的时候,由于abaqus运行explicit package,所以软件在正式计算前会先检查材料参数。实际上,abaqus explicit package 检查的是 stressNew 输出的数值是否正确。如果stressNew 定义的值不正确,或者没有定义,abaqus会出现如下error:
Bad Material definition in element number 1 instance PART-1-1: zero or negative initial dilatational modulus caused by bad material data. Please check your material input and any initial conditions if necessary.
所以本文为了让vumat可以正常运行,所以在代码中加入三行语句:
DO k=1,nblock 是vumat中特有的,配合平行计算进行的语句,如果用户在提交任务时打开了平行计算且模型中使用了多个单元,这个DO语句是必要的。
strainInc之前乘以任何大于0的数都是可以的,但是如果是负数或者0,则会出现Bad Material definition.....的错误。直接将stressNew等于某个数也有可能会出现该错误。
注:该错误提示只有在使用vumat的时候才需要注意,在使用umat的时候,abaqus standard package没有类似问题。
另外,在代码中还有额外的一些辅助语言,比如,
该语句是为了在.log文件中方便确定输出的结果来自哪一个时间步。.log文件可以在work directionary中找到,
1 Variables
以下是允许的参数名称:
参数开头必须是字母,参数中可以使用下划线和数字,但是不能带字符(除%外)和空格。以下是错误的参数名称示范:
注:一些参数名称中会带有%,涉及到 pointer 和 reference ,不展开介绍,感兴趣的读者可以参考Fortran95的手册。
在程序开头,一般需要申明变量,Fortran中常用的变量有:
它们的使用案例为:
为了确定变量的精度,可以在申明变量的时候在括号中定义。Fortran提供了内置function:selected real kind 用于确定变量的精度。对于大部分CPU:
通过以下案例,可以比较定义和不定义精度对数值的影响:
输出结果:
可以如果不在声明变量的时候定义精度,变量的结果会发生改变。
对于logical变量,只能定义 .true. 或者 .false.
对于数组(变量或者矩阵),可以有多种定义方式。如下,
输出结果为:
对向量v和矩阵A进行修改,比如:
可以得到如下结果:
Fortran还可以计算多阶数组,包括了比如张量的计算。在固体力学中,最常见的张量计算是4阶的刚度矩阵乘以2阶的应变得到2阶的应力,比如:
C_{ijkl} \varepsilon_{kl} = \sigma_{ij}C_{ijkl} \varepsilon_{kl} = \sigma_{ij}
代码案例如下,
输出结果为:
可以发现将 C(1, 2, k, l) 和 e_strain(k, l) 点乘求和的值(即 5X2 + 6X3 + 7X4 + 6X3 ..... )等于 sigma(1,2) = 264。
2 Operatorer
常见的运算符有,
常见的关系符有,
常见的逻辑符有,
3. Conditional statements
常见的条件语句有两种,分别是 if 和 select, 它们的结构为:
这两种语句在大部分编程语言中都很常见。由于 IF 语句可以多层嵌套,所以可以在IF之前加上名称,以免混淆。比如,
输出结果,
4. Repetitive statements
循环语句是计算科学中最最最常用的语句。首先介绍do语句和do while语句的用法,它们的结构为,
它们经常配合 if 语句完成循环的任务,
输出结果:
和 if 类似,do 之前也可以命名,方便在多层嵌套循环中离开某个循环。比如,有3层循环,从外到内分别为loop1, loop2, loop3,当 loop3 中满足某个条件时,代码需要离开loop2,但是留在 loop1 中。 假设有三层嵌套语句如下,
输出结果为:
现在在loop3中要求满足条件时,代码离开loop2但是保留在loop1中,代码修改为,
输出结果为:
之前计算张量的时候用过 forall 语句,它和 do 语句功能相同,结构如下:
Fortran中还有一种 where 语句,其结合了 if 和 do 的功能,常用于对数组进行修改,结构如下,
输出结果:
5. 内置function和自定义function
自定义function的结构为,
自定义function的调用案例如下,
输出结果为:
此外,在创建数组的时候,可以采用implicit do的方式直接确立数组中的内容,
上面代码中,A_mat 是一个通过改变 A2_vector 尺寸得到的矩阵。reshape函数中的order十分重要,因为默认的排列顺序是从上往下排列,order = (/2,1/)可以要求数组从左到右排列。
6. subroutine
子程序不仅可以被主程序调用,也可以被其他子程序调用。以二力杠单元局部单元刚度转换为整体单元刚度为例,介绍子程序调用方法。
整体坐标系中的单元刚度为,
其中,局部单元刚度为,
转化矩阵为,
二力杠两点的坐标以及弹模和截面积设为,
代码如下,
输出结果为:
7. Modules
从Fortran90开始,Modules逐渐开始被接受。Modules的格式为:
对之前的子程序进行修改,将 subroutine bar3e 放到 modules 中。在subroutine vumat中,我们采用了动态变量,其格式和使用方法有三个步骤。(1)在前期声明的时候,
(2)在程序中使用的时候,需要具体确定它们的尺寸
(3)使用完以后需要取消定义它们,
注:Modules一般放在程序的开头。use的位置很重要,一定要放在subroutine vumat的开始位置。
输出结果为:
8. Others
8.1 Stop 和 Return 的区别
Stop表示停止子程序运行。一旦子程序停止运行,ABAQUS求解器也会停止运算,监控器里没有时间步数,但是状态是“completed“。如下所示:
输出结果为
监视器状态为:
如果使用Return,子程序会在return出现的时候结束运行,但求解器不会停止,而是进入下一个时间步。
8.2 Assumed-Shape Arrays
某些子程序需要从主程序获取矩阵信息,比如矩阵的尺寸。但是很多时候主程序中的矩阵尺寸是动态变化的。为了解决这个问题,可以定义子程序中的矩阵为Assumed-Shape Arrays。主程序实例为:
其中umat_printArray的功能是打印任意尺寸的矩阵
得到的结果为:
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删