Kob*_*obs 5 fortran fortran77 finite-element-analysis
我有两个小的用户定义的子程序,我已经在有限元软件ABAQUS中实现了(它们在我的有限元模型中定义了两种特殊类型(JTYPE = 1,2)的多点约束(MPC)).这些子程序根据需要在FORTRAN 66/77中编写,并由ABAQUS在运行时使用Intel FORTRAN编译器进行编译.我已经验证他们编译并正常工作.
但是,我只能在我的模型中一次使用其中一个子程序.这是因为他们必须使用以下名称和参数(为了让ABAQUS知道何时调用它们以及如何使用它们):
SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
* LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)
Run Code Online (Sandbox Code Playgroud)
然而,事实证明,我需要能够在给定的分析中同时使用这两种类型.由于为我的有限元模型中使用的每个MPC实例指定的JTYPE是1或2,因此理想的解决方案是组合我当前单独的子例程,并在这个新子例程内的两种类型之间切换.我想我可以使用IF(JTYPE .EQ.1)THEN类型语法来做到这一点.
问题是每个JTYPE所需的代码块都不同,即使它们都是SUBROUTINE MPC.对于我的第一个子例程(JTYPE = 1),手册需要以下界面:
SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
* LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)
C
INCLUDE 'ABA_PARAM.INC'
C
DIMENSION A(N),JDOF(N),X(6,N),U(MAXDOF,N),UINIT(MAXDOF,N),
* TIME(2),TEMP(NT,N),FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N)
user coding to define A, JDOF, and, optionally, LMPC
RETURN
END
Run Code Online (Sandbox Code Playgroud)
对于第二个子例程(JTYPE = 2),手册需要以下接口:
SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
* LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)
C
INCLUDE 'ABA_PARAM.INC'
C
DIMENSION UE(MDOF),A(MDOF,MDOF,N),JDOF(MDOF,N),X(6,N),
* U(MAXDOF,N),UINIT(MAXDOF,N),TIME(2),TEMP(NT,N),
* FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N)
user coding to define JDOF, A and, optionally, LMPC
RETURN
END
Run Code Online (Sandbox Code Playgroud)
重要的区别在于A和JDOF阵列的尺寸对于每种类型都是不同的.
我希望通过在IF循环中声明这些变量来解决这个问题,如下所示:
SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
* LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)
C
C CUSTOM MULTI POINT CONSTRAINT
C
INCLUDE 'ABA_PARAM.INC'
C
DIMENSION A(N),JDOF(N),X(6,N),U(MAXDOF,N),UINIT(MAXDOF,N),
* TIME(2),TEMP(NT,N),FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N),
* A_2(MDOF,MDOF,N),JDOF_2(MDOF,N),UE(MDOF)
C
IF (JTYPE .EQ. 1) THEN
DIMENSION A(N),JDOF(N),X(6,N),U(MAXDOF,N),UINIT(MAXDOF,N),
* TIME(2),TEMP(NT,N),FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N),
* A_2(MDOF,MDOF,N),JDOF_2(MDOF,N),UE(MDOF)
A(1) = 1.
A(2) = -1.
JDOF(1) = 3
JDOF(2) = 3
END IF
C
IF (JTYPE .EQ. 2) THEN
DIMENSION UE(MDOF),A(MDOF,MDOF,N),JDOF(MDOF,N),X(6,N),
* U(MAXDOF,N),UINIT(MAXDOF,N),TIME(2),TEMP(NT,N),
* FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N)
DATA H /2.000000e-03/
A(1,1,1) = 1.
A(2,2,1) = 1.
A(3,3,1) = 1.
A(1,1,2) = -1.
A(1,5,2) = H
A(2,2,2) = -1.
A(2,4,2) = H
A(3,3,2) = -1.
JDOF(1,1) = 1
JDOF(2,1) = 2
JDOF(3,1) = 3
JDOF(1,2) = 1
JDOF(2,2) = 2
JDOF(3,2) = 3
JDOF(4,2) = 4
JDOF(5,2) = 5
END IF
C
RETURN
END
Run Code Online (Sandbox Code Playgroud)
但是,这会导致编译在运行时失败,ABAQUS会吐出以下错误:
作业错误Job-1:编译期间出现问题 - C:\ Users\kbodjo\Documents\Abaqus Analyses\custom_MPC_3.for Job Job-1因错误而中止.
考虑到上述挑战,我如何实现组合这两个MPC子程序的目标?
编辑这是代码修复的方式,它现在可以工作:
SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
* LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)
C
C CUSTOM MULTI POINT CONSTRAINT
C
INCLUDE 'ABA_PARAM.INC'
C
DIMENSION UE(MDOF),A(MDOF*MDOF*N),JDOF(MDOF*N),X(6,N),U(MAXDOF,N),
* UINIT(MAXDOF,N),
* TIME(2),TEMP(NT,N),FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N)
C
IF (JTYPE .EQ. 1) THEN
A(1) = 1.
A(2) = -1.
JDOF(1) = 3
JDOF(2) = 3
END IF
C
IF (JTYPE .EQ. 2) THEN
C
DATA H /2.000000e-03/
A((1-1)*MDOF*MDOF + (1-1)*MDOF + 1) = 1.
A((1-1)*MDOF*MDOF + (2-1)*MDOF + 2) = 1.
A((1-1)*MDOF*MDOF + (3-1)*MDOF + 3) = 1.
A((1-1)*MDOF*MDOF + (1-1)*MDOF + 2) = -1.
A((2-1)*MDOF*MDOF + (5-1)*MDOF + 1) = H
A((2-1)*MDOF*MDOF + (2-1)*MDOF + 2) = -1.
A((2-1)*MDOF*MDOF + (4-1)*MDOF + 2) = H
A((2-1)*MDOF*MDOF + (3-1)*MDOF + 3) = -1.
C
JDOF((1-1)*MDOF + 1) = 1
JDOF((1-1)*MDOF + 2) = 2
JDOF((1-1)*MDOF + 3) = 3
JDOF((2-1)*MDOF + 1) = 1
JDOF((2-1)*MDOF + 2) = 2
JDOF((2-1)*MDOF + 3) = 3
JDOF((2-1)*MDOF + 4) = 4
JDOF((2-1)*MDOF + 5) = 5
END IF
C
RETURN
END
Run Code Online (Sandbox Code Playgroud)
编译错误对我来说似乎很正常。据我所知,首先在可执行指令之前声明变量。现在,由于您使用的 fortran 66/77 不会在编译时检查参数类型,因此一种解决方案是在这两种情况下将 A 和 JDOF 视为一个一维数组。利用 Fortran 按列存储数组的事实,您可以通过索引转换来获取每个元素的位置。如果你的代码真的那么简单,它也会非常简单。对于数组参数,fortran 实际上传递第一个元素的地址。
例如,将 A 和 JDOF 声明为
DIMENSION A(MDOF*MDOF*N),JDOF(MDOF*MDOF*N)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,情况 1 都很简单,而对于情况 2,您有以下索引翻译:
A(1,1,1) becomes A(1)
A(2,1,1) becomes A(2)
Run Code Online (Sandbox Code Playgroud)
等等。作为较大情况的公式,对于最初的数组
A(MDOF,MDOF,N)
A(i,j,k) becomes A( (k-1)*MDOF*MDOF + (j-1)*MDOF + i)
Run Code Online (Sandbox Code Playgroud)