Ошибка сегментации подпрограммы - PullRequest
0 голосов
/ 20 февраля 2020
PROGRAM olaf
IMPLICIT NONE
INTEGER                                  :: i, j, nc, nd,ok,iter
REAL                                     :: alph, bet, chi, ninf1, C1, ninf2, C2
REAL, DIMENSION(:), ALLOCATABLE          :: u,up2
REAL                                     :: E, k, Lc, hc, eps, h, Ld, Cai
INTEGER, DIMENSION(7)                    :: valnc = (/ 10, 50, 100, 500, 1000, 5000, 10000/)



Do iter=1,7
 nc = valnc(iter)
 Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;

 E=25. ; k=125. ; hc=0.01 ; eps=0.01 ; Lc=1 ;

 h = Lc/nc ; chi=sqrt((E*hc)/k) ; alph= -(1/h**2) ; bet=(2/h**2)+(k/(E*hc)) ;


 CALL resolution(0,nc,bet,2*alph,alph,2*alph,-2*eps/h,2*eps/h,u)
 Cai=u(nc)
 CALL resolution(nc+1,(nc+nd)+1,-2.0,2.0,1.0,2.0,2.0*eps*h,-2*eps*h,up2,Cai)


 DEALLOCATE(u,up2)
END DO

CONTAINS

SUBROUTINE resolution (n1,n2,a,b1,b,b2,c1,c2,u1,u2)
 INTEGER, INTENT(IN) :: n1,n2
 REAL, INTENT(IN):: a,b1,b,b2,c1,c2
 REAL, INTENT(IN),OPTIONAL :: u2
 REAL, DIMENSION (:),ALLOCATABLE, INTENT(OUT) :: u1
 REAL, DIMENSION(:), ALLOCATABLE          :: Ap, Ae, Aw, bh, Lw, Lp, Ue, y
 INTEGER :: i
 Logical :: Exist

 ALLOCATE(Ap(n1+1:n2), Ae(n1:n2), Aw(n1:n2),bh(n1:n2))
 ALLOCATE(Lw(n1:n2), Lp(n1:n2), Ue(n1:n2), y(n1:n2),u1(n1:n2))

 Aw=0; Ap=0; Ae=0; bh= 0 ; Lw = 0 ; Lp = 0 ; Ue = 0 ; y=0; Lc=0;

 Exist=Present(u2)
 IF(Exist .eqv. .true.)THEN
  u1(n1)=u2
 END IF

DO i = n1,n2
  Ae(i) = b
  Ap(i) = a
  Aw(i) = b
END DO
Ae(n1)=b1
Aw(n2)=b2

bh(n1)=c1
bh(n2)=c2

Lp(n1) = Ap(n1+2)
Ue(n1) = Ae(n1)/Lp(n1)

DO i = n1+1, n2-1
 Lw(i) = Aw(i)
 Lp(i) = Ap(i) - Lw(i)*Ue(i-1)
 Ue(i) = Ae(i)/Lp(i)
END DO

Lw(n2) = Aw(n2)
Lp(n2) = Ap(n2) - Lw(n2)*Ue(n2-1)
y(n1) = bh(n1)/Lp(n1)

DO i = n1, n2
  y(i) = (bh(i) - Lw(i)*y(i-1)) / Lp(i)
END DO

u1(n2) = y(n2)
DO i = n2-1, n1, -1
 u1(i) = y(i) - Ue(i)*u1(i+1)
END DO

DEALLOCATE(Ap, Ae, Aw,bh,Lw, Lp, Ue, y)

END SUBROUTINE

END PROGRAM olaf

Я пытаюсь выполнить разложение Ah = b для u и up2 в моей программе. Тем не менее, up2 зависит от вас для его первого значения. Чтобы не повторять разрешение разложения, я превратил его в подпрограмму, но всякий раз, когда я пытаюсь вызвать его в одном и том же l oop как для u, так и для up2, я продолжаю получать ошибку sigmentation, которую я не могу идентифицировать.

1 Ответ

1 голос
/ 20 февраля 2020

Пожалуйста, ознакомьтесь с предупреждениями компилятора и проверкой ошибок во время выполнения. Используя gfortran с соответствующими флагами в вашей программе, я получаю:

ijb@ianbushdesktop ~/work/stack $ gfortran -std=f2003 -Wall -Wextra -fcheck=all -g -O olaf.f90 
olaf.f90:13:16:

  Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;
                1
Warning: Possible change of value in conversion from REAL(4) to INTEGER(4) at (1) [-Wconversion]
olaf.f90:4:69:

 REAL                                     :: alph, bet, chi, ninf1, C1, ninf2, C2
                                                                     1
Warning: Unused variable ‘c1’ declared at (1) [-Wunused-variable]
olaf.f90:4:80:

 REAL                                     :: alph, bet, chi, ninf1, C1, ninf2, C2
                                                                                1
Warning: Unused variable ‘c2’ declared at (1) [-Wunused-variable]
olaf.f90:3:45:

 INTEGER                                  :: i, j, nc, nd,ok,iter
                                             1
Warning: Unused variable ‘i’ declared at (1) [-Wunused-variable]
olaf.f90:3:48:

 INTEGER                                  :: i, j, nc, nd,ok,iter
                                                1
Warning: Unused variable ‘j’ declared at (1) [-Wunused-variable]
olaf.f90:4:65:

 REAL                                     :: alph, bet, chi, ninf1, C1, ninf2, C2
                                                                 1
Warning: Unused variable ‘ninf1’ declared at (1) [-Wunused-variable]
olaf.f90:4:76:

 REAL                                     :: alph, bet, chi, ninf1, C1, ninf2, C2
                                                                            1
Warning: Unused variable ‘ninf2’ declared at (1) [-Wunused-variable]
olaf.f90:3:59:

 INTEGER                                  :: i, j, nc, nd,ok,iter
                                                           1
Warning: Unused variable ‘ok’ declared at (1) [-Wunused-variable]
olaf.f90:13:0:

  Ld=0.2*Lc ; nd=((Lc+Ld)/h)-nc;

Warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized]
olaf.f90:6:0:

 REAL                                     :: E, k, Lc, hc, eps, h, Ld, Cai

note: ‘h’ was declared here
ijb@ianbushdesktop ~/work/stack $ ./a.out
At line 51 of file olaf.f90
Fortran runtime error: Index '0' of dimension 1 of array 'ap' below lower bound of 1

Error termination. Backtrace:
#0  0x400f8d in resolution
    at /home/ijb/work/stack/olaf.f90:51
#1  0x401991 in olaf
    at /home/ijb/work/stack/olaf.f90:20
#2  0x401991 in main
    at /home/ijb/work/stack/olaf.f90:11
ijb@ianbushdesktop ~/work/stack $ 

Обратите внимание на две вещи

  1. Вы используете h неинициализирован. Компилятор сообщит вам об этом со второго по последнее предупреждение. Я не знаю, как это исправить, вам нужно это сделать.
  2. Вы обращаетесь к массиву ap за пределами. Это происходит на линии

    Ap (i) = a

, и проблема в том, что i равен нулю. Глядя на код i, вы переходите от n1 к n2, поэтому основная проблема заключается в том, что в строке

  CALL resolution(0,nc,bet,2*alph,alph,2*alph,-2*eps/h,2*eps/h,u)

вы передаете значение от 0 до n1, но выделяете массив ap как

 ALLOCATE(Ap(n1+1:n2), Ae(n1:n2), Aw(n1:n2),bh(n1:n2))

, что несовместимо с приведенным выше использованием Ap. Мое полное предположение состоит в том, что do l oop должен читаться как

DO i = n1+1,n2

, но это предположение - проблема в том виде, в каком она представлена, из-за ошибок "за пределами границ" в этом l oop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...