5

我在有限元软件 ABAQUS 中实现了两个小的用户定义子程序(它们在我的有限元模型中定义了多点约束 (MPC) 的两种特殊类型 (JTYPE=1,2))。这些子程序根据需要用 FORTRAN 66/77 编写,并由 ABAQUS 在运行时使用英特尔 FORTRAN 编译器进行编译。我已经验证它们可以正确编译和工作。

但是,我在我的模型中一次只能使用其中一个子例程。这是因为它们都必须使用以下名称和参数(以便 ABAQUS 知道何时调用它们以及如何使用它们):

      SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,
     * LMPC,KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,LTRAN,TRAN)

然而,事实证明,我需要能够在给定的分析中同时使用这两种类型。由于为我的有限元模型中使用的许多 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

对于第二个子程序(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

重要的区别在于 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

但是,这会导致编译在运行时失败,ABAQUS 会出现以下错误:

作业 Job-1 出错:编译期间出现问题 - C:\Users\kbodjo\Documents\Abaqus Analyses\custom_MPC_3.for 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
4

1 回答 1

3

编译错误对我来说似乎很正常。据我所知,您首先在可执行指令之前声明变量。现在,由于您使用的 fortran 66/77 在编译时不检查参数类型,因此一种解决方案是在两种情况下都将 A 和 JDOF 视为一个一维数组。使用 fortran 按列存储数组的事实,您都可以通过索引转换来获取每个元素的位置。如果你的代码真的那么简单,它也将非常简单。对于数组参数,fortran 实际上传递了第一个元素的地址。

例如,将 A 和 JDOF 声明为

DIMENSION A(MDOF*MDOF*N),JDOF(MDOF*MDOF*N)

在这两种情况下,案例 1 都很简单,对于案例 2,您有以下索引翻译:

A(1,1,1) becomes A(1)
A(2,1,1) becomes A(2)

等等。作为较大情况的公式,对于您最初的数组

A(MDOF,MDOF,N)
A(i,j,k) becomes A( (k-1)*MDOF*MDOF + (j-1)*MDOF + i)
于 2014-03-30T03:57:52.147 回答