Как решить ошибку NaN и Invalid в Fortran - PullRequest
0 голосов
/ 01 августа 2020

Все мои выходные данные - NaN, и стандартная ошибка - «IEEE_INVALID_FLAG». Я отлаживаю код в gdb и обнаруживаю, что первая строка IEEE_INVALID_FLAG - это строка 281:

Program received signal SIGFPE, Arithmetic exception.
0x000055555555c830 in calcu () at SIMPLE-2D.f:281
281      &      +(1.-URFU)*U(I,J)

Код для строки 281 - это выражение для введите здесь описание изображения , а полный код:

      U(I,J)=URFU/APU(I,J)*
     &      (AEEU(I,J)*U(I+2,J)+AEU(I,J)*U(I+1,J)
     &      +AWWU(I,J)*U(I-2,J)+AWU(I,J)*U(I-1,J)
     &      +ANNU(I,J)*U(I,J+2)+ANU(I,J)*U(I,J+1)
     &      +ASSU(I,J)*U(I,J-2)+ASU(I,J)*U(I,J-1)
     &      +(P(I,J)-P(I+1,J))*DY)
     &      +(1.-URFU)*U(I,J)

I = 1: 79, J = 1: 80. AEEU, AEU, ... - это матрица 79 * 80. Может ли кто-нибудь дать мне некоторое представление об этой ошибке? Большое спасибо!

1 Ответ

1 голос
/ 04 августа 2020

В большинстве случаев NaN являются результатом операций с бесконечностями, например Infinity * 2 = NaN. Как следует из вывода компилятора, у вас есть как переполнение , так и переполнение . Переполнение происходит, когда тип переменной не может содержать число, потому что показатель степени положительный и слишком большой (очень большое число), а недостаточное заполнение происходит, когда число слишком мало, потому что показатель степени отрицательный и слишком большой (очень маленькое число). Попробуйте изменить свой код, чтобы использовать реальную двойную точность. В FORTRAN 77 этого можно достичь с помощью типа DOUBLE PRECISION:

DOUBLE PRECISION URFU
DOUBLE PRECISION U(:,:)

В современном Фортране вы можете использовать что-то вроде этого:

INTEGER, PARAMETER :: dp = KIND(1.D0)
REAL(KIND=dp) :: URFU, U(:,:)
...