0

我是 Fortran 新手,我遇到了这个问题。

当我运行这个 DO 就可以了:

integer, parameter :: Int10Type = selected_int_kind (10)
INTEGER (Int10Type), PARAMETER :: TOTAL_TIME = 1000, TOTAL_INI = 200
INTEGER (Int10Type):: t, z
REAL (16), DIMENSION(TOTAL_Z, TOTAL_TIME) :: current
DO t = 1, TOTAL_TIME
   current(TOTAL_Z, t) = TEMP_INI
END DO
DO t = 1, TOTAL_TIME - 1
  DO z = 2, (TOTAL_Z - 1)
    current(z, t + 1) = current (z, t) + KAPPA*DELTA_T*((current(z - 1, t) -2.0*current(z, t) + current(z + 1, t)) / DELTA_Z**2)
  END DO
END DO

但是,当我增加 var limite

    integer, parameter :: Int10Type = selected_int_kind (10)
INTEGER (Int10Type), PARAMETER :: TOTAL_TIME = 1000000000, TOTAL_INI = 200
INTEGER (Int10Type):: t, z
REAL (16), DIMENSION(TOTAL_Z, TOTAL_TIME) :: current
DO t = 1, TOTAL_TIME
   current(TOTAL_Z, t) = TEMP_INI
END DO
DO t = 1, TOTAL_TIME - 1
  DO z = 2, (TOTAL_Z - 1)
    current(z, t + 1) = current (z, t) + KAPPA*DELTA_T*((current(z - 1, t) -2.0*current(z, t) + current(z + 1, t)) / DELTA_Z**2)
  END DO
END DO

程序的输出是'killed'
为什么?我做错了什么?

4

1 回答 1

1

integer(10)表示integer(kind=10),不是至少有 10 位小数的整数。kind=10 的含义取决于编译器。不能保证 kind=10 甚至存在!如果要指定 10 位十进制数字,则应使用:

integer, parameter :: Int10Type = selected_int_kind (10)
integer (kind=Int10Type) :: i

然后将您的程序编写为:

integer, parameter :: Int10Type = selected_int_kind (10)

INTEGER (Int10Type), PARAMETER :: limite = 1000000000_Int10Type, lim = 200
INTEGER (Int10Type):: i, j
DO i = 1, limite
  DO j = 1, lim
     !I work with a matrix
  END DO
END DO

请注意,在大常量值上也指定了类型。

或者,如果您的编译器提供 Fortran 2003 的 ISO Fortran 环境功能,您可以以可移植的方式请求一个 8 字节(64 位)整数:

use iso_fortran_env

INTEGER (INT64), PARAMETER :: limite = 1000000000_INT64, lim = 200
INTEGER (INT64):: i, j
DO i = 1, limite
  DO j = 1, lim
     !I work with a matrix
  END DO
END DO

PS 1000000000 应该适合 4 字节(有符号)整数,因为 2**31 = 2,147,483,648,因此大多数 Fortran 编译器的默认整数应该可以工作。您可能只使用integer而不指定种类!iso_fortran_env,INT32应该足够了。如果这不能解决您的问题,可能是您的数组太大了……您可能需要向我们展示更多代码。

PPS 响应附加源代码。tdo 循环从 1 到total_time,但您使用第二个索引作为,t+1这意味着最大值将是total_time+1。这超过了 的第二维current。您有一个数组下标错误。如果您使用下标边界进行编译,则编译器会为您找到它。对于 gfortran,可以使用 -fcheck=all 或 -fbounds-check。

于 2013-03-05T08:01:41.913 回答