F.N.B
F.N.B

Reputation: 1619

upper limit DO Fortran

I am new in Fortran and i have this problem.

When i ran this DO is ok:

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

But, when i increment 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

The output of the program is 'killed'
Why? what i do bad?

Upvotes: 0

Views: 416

Answers (1)

M. S. B.
M. S. B.

Reputation: 29401

integer(10) means integer(kind=10), not an integer with at least 10 decimal digits. It is up to a compiler what kind=10 means. There is no guarantee that kind=10 even exists! If you want to specify 10 decimal digits you should use:

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

Then write your program as:

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

Notice that the type has also been specified on the large constant value.

Alternatively, if your compiler provides the ISO Fortran Environment feature of Fortran 2003, you can request an 8 byte (64 bit) integer in a portable way:

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

P.S. 1000000000 should fit into a 4-byte (signed) integer since 2**31 = 2,147,483,648, so the default integer of most Fortran compilers should work. You can probably just use integer without specifying a kind! With iso_fortran_env, INT32 should suffice. If this doesn't solve your problem, perhaps your array is too big ... you may need to show us more code.

P.P.S. In response to the additional source code. The t do loop goes from 1 to total_time, but you use the 2nd index as t+1, which means that the largest value will be total_time+1. This exceeds the 2nd dimension of current. You have an array subscripting error. If you compile with subscript bounds checking the compiler will find this for you. With gfortran, either use -fcheck=all or -fbounds-check.

Upvotes: 1

Related Questions