组合两个Fortran子程序以与ABAQUS一起使用

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)

inn*_*SPG 3

编译错误对我来说似乎很正常。据我所知,首先在可执行指令之前声明变量。现在,由于您使用的 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)