2013-08-05 2 views
1

runge-kutt 방법으로 2 몸체 문제를 해결하는 프로그램을 만듭니다. 나는 문제에 직면했다 : 2 차원 배열의 요소를 표현식에서 2 차원 배열의 요소를 반환하는 함수를 호출 할 때 (용어와 혼동하여 미안하다) 나는 다음 메시지를 받는다.오류 # 6366 : 배열 표현의 모양이 일치하지 않습니다

error #6366: The shapes of the array expressions do not conform. 
[X1] 
     X1(DIM,i)=X1(DIM,i-1)+0.5D0*ABS(i/2)*H*K1(DIM,i-1,X1(DIM,i-1),X2(DIM,i-1),V1(DIM,i-1),V2(DIM,i-1),NDIM,ORD,2,maxnu) 

이 함수에 대한 외부 인터페이스가 있으며 컴파일러가이 함수를 함수라고 생각합니다.

내가 몇 가지를 명확히해야합니다

예, 그것은 아주 포트란 아니다, 그것은 모스크바 대학에서 천문학 (난 그냥 학생입니다)에 의해 사용되는 전처리 Trefor가 있습니다. 이 언어는 포트란과 매우 비슷하지만 많은 학생들이 공부하는 C (예 : 세미콜론)에 조금 가깝습니다. 룽게 - 쿠타 방법은 간단히 같이 쓸 수있다 : 우리 초기치 문제가

dy/dt=f(t,y), y(t0)=y0 

Y 제 경우 12 개 성분 (3 개 좌표와 각 신체 3 개 속도)

포함 미지의 벡터이고, 다음 단계는

y(n+1)=y(n)+1/6*h*(k1+2k2+2k3+k4), t(n+1)=t(n)+h 
where 
k1=f(tn,yn), 
k2=f(tn+1/2h,yn+h/2*k1) 
k3=f(tn+1/2h,yn+h/2*k2) 
k4=f(tn+1/2h,yn+k3) 

e 내 코드 X1,2 및 V1,2와 K_1,2는 벡터가되어야합니다. 각 요소는 메소드의 각 '순서'에 대해 3 개의 공간 구성 요소와 4 개의 구성 요소를 가져야하기 때문에 벡터입니다. 전체 코드 :

FUNCTION K1(DIM,i,X1,X2,V1,V2,NDIM,ORD,nu,maxnu)RESULT (K_1); 
     integer,intent(in) :: i,DIM,nu; 
     real(8) :: K_1; 
     real(8) :: B1; 
     real(8) :: R; 
     real(8),intent(in) :: X1,X2,V1,V2; 
COMMON/A/M1,M2,Fgauss,H; 
     integer,intent(in) :: NDIM,ORD,maxnu; 
Dimension :: B1(NDIM, ORD); 
Dimension :: X1(NDIM,ORD),X2(NDIM,ORD),V1(NDIM,ORD),V2(NDIM,ORD); 
Dimension :: K_1(NDIM,ORD); 
    IF (nu>=2) THEN; 
B1(DIM,i)=V1(DIM,i); 
ELSE; 
R=((X1(1,i)-X2(1,i))**2.D0+(X1(2,i)-X2(2,i))**2.D0+(X1(3,i)-X2(3,i))**2.D0)**0.5D0; 
B1(DIM,i)=Fgauss*M2*(X2(DIM,i)-X1(DIM,i))/((R)**3.D0); 
    END IF; 
K_1(DIM,i)=B1(DIM,i); 
     RETURN; 
    END FUNCTION K1; 

FUNCTION K2(DIM,i,X1,X2,V1,V2,NDIM,ORD,nu,maxnu)RESULT (K_2); 
     integer,intent(in) :: i,DIM,nu; 
     real(8) :: K_2; 
     real(8) :: B2; 
     real(8) :: R; 
     real(8),intent(in) :: X1,X2,V1,V2; 
COMMON/A/M1,M2,Fgauss,H; 
     integer,intent(in) :: NDIM,ORD,maxnu; 
Dimension :: B2(NDIM,ORD); 
Dimension :: X1(NDIM,ORD),X2(NDIM,ORD),V1(NDIM,ORD),V2(NDIM,ORD); 
Dimension :: K_2(NDIM,ORD); 
    IF (nu>=2) THEN; 
B2(DIM, i)=V2(DIM,i); 
ELSE; 
R=((X1(1,i)-X2(1,i))**2.D0+(X1(2,i)-X2(2,i))**2.D0+(X1(3,i)-X2(3,i))**2.D0)**0.5D0; 
B2(DIM, i)=Fgauss*M1*(X2(DIM,i)-X1(DIM,i))/((R)**3.D0); 
    END IF; 
K_2(DIM,i)=B2(DIM, i); 
     RETURN; 
     END FUNCTION K2; 

PROGRAM RUNGEKUTT; 
    IMPLICIT NONE; 
    Character*80 STRING; 
real(8) :: M1,M2,Fgauss,H; 
real(8) :: R,X1,X2,V1,V2; 
integer :: N,i,DIM,NDIM,maxnu,ORD; 
integer :: nu; 
PARAMETER(NDIM=3,ORD=4,maxnu=2); 
    Dimension :: X1(NDIM,ORD),X2(NDIM,ORD); 
    Dimension :: V1(NDIM,ORD),V2(NDIM,ORD); 
INTERFACE; 
    FUNCTION K1(DIM,i,X1,X2,V1,V2,NDIM,ORD,nu,maxnu)RESULT (K_1); 
     integer,intent(in) :: i,DIM,nu; 
     real(8) :: K_1; 
     real(8) :: R; 
     real(8) :: B1; 
     real(8),intent(in) :: X1,X2,V1,V2; 
COMMON/A/M1,M2,Fgauss,H; 
     integer,intent(in) :: NDIM,ORD,maxnu; 
Dimension :: B1(NDIM, ORD); 
Dimension :: X1(NDIM,ORD),X2(NDIM,ORD),V1(NDIM,ORD),V2(NDIM,ORD); 
Dimension :: K_1(NDIM,ORD); 
END FUNCTION K1; 
FUNCTION K2(DIM,i,X1,X2,V1,V2,NDIM,ORD,nu,maxnu)RESULT (K_2); 
     integer,intent(in) :: i,DIM,nu; 
     real(8) :: K_2; 
     real(8) :: R; 
     real(8) :: B2; 
     real(8),intent(in) :: X1,X2,V1,V2; 
COMMON/A/M1,M2,Fgauss,H; 
     integer,intent(in) :: NDIM,ORD,maxnu; 
Dimension :: B2(NDIM,ORD); 
Dimension :: X1(NDIM,ORD),X2(NDIM,ORD),V1(NDIM,ORD),V2(NDIM,ORD); 
Dimension :: K_2(NDIM,ORD); 
END FUNCTION K2; 
END INTERFACE; 
     open(1,file='input.dat'); 
     open(2,file='result.res'); 
     open(3,file='mid.dat'); 
    READ(1,'(A)') STRING; 
    READ(1,*) Fgauss,H; 
    READ(1,*) M1,M2; 
    READ(1,*) X1(1,1),X1(2,1),X1(3,1),V1(1,1),V1(2,1),V1(3,1); 
    READ(1,*) X2(1,1),X2(2,1),X2(3,1),V2(1,1),V2(2,1),V2(3,1); 
    WRITE(*,'(A)') STRING; 
    WRITE(3,'(A)') STRING; 
    WRITE(3,'(A,2G14.6)')' Fgauss,H:',Fgauss,H; 
    WRITE(3,'(A,2G14.6)')' M1,M2:',M1,M2; 
    WRITE(3,'(A,6G17.10)')' X1(1,1),X1(2,1),X1(3,1),V1(1,1),V1(2,1),V1(3,1):',X1(1,1),X1(2,1),X1(3,1),V1(1,1),V1(2,1),V1(3,1); 
    WRITE(3,'(A,6G17.10)')' X2(1,1),X2(2,1),X2(3,1),V2(1,1),V2(2,1),V2(3,1):',X2(1,1),X2(2,1),X2(3,1),V2(1,1),V2(2,1),V2(3,1); 
    R=((X1(1,1)-X2(1,1))**2.D0+(X1(2,1)-X2(2,1))**2.D0+(X1(3,1)-X2(3,1))**2.D0)**0.5D0; 
     N=0; 

     _WHILE N<=100 _DO; 
     i=2; 
      _WHILE i<=ORD _DO; 
     DIM=1; 

      _WHILE DIM<=NDIM _DO; 
X1(DIM,i)=X1(DIM,i-1)+0.5D0*ABS(i/2)*H*K1(DIM,i-1,X1(DIM,i-1),X2(DIM,i-1),V1(DIM,i-1),V2(DIM,i-1),NDIM,ORD,2,maxnu); 
X2(DIM,i)=X2(DIM,i-1)+0.5D0*H*ABS(i/2)*K2(DIM,i-1,X1(DIM,i-1),X2(DIM,i-1),V1(DIM,i-1),V2(DIM,i-1),NDIM,ORD,2,maxnu); 
V1(DIM,i)=V1(DIM,i-1)+0.5D0*H*ABS(i/2)*K1(DIM,i-1,X1(DIM,i-1),X2(DIM,i-1),V1(DIM,i-1),V2(DIM,i-1),NDIM,ORD,1,maxnu); 
V2(DIM,i)=V2(DIM,i-1)+0.5D0*H*ABS(i/2)*K2(DIM,i-1,X1(DIM,i-1),X2(DIM,i-1),V1(DIM,i-1),V2(DIM,i-1),NDIM,ORD,1,maxnu); 

       DIM=DIM+1; 
       _OD; 
      i=i+1; 
     _OD; 

     _WHILE DIM<=NDIM _DO; 
X1(DIM,1)=X1(DIM,1)+1.D0/6.D0*H*(K1(DIM,1,X1(DIM,1),X2(DIM,1),V1(DIM,1),V2(DIM,1),NDIM,ORD,2,maxnu)+2.D0*K1(DIM,2,X1(DIM,2),X2(DIM,2),V1(DIM,2),V2(DIM,2),NDIM,ORD,2,maxnu)+2.D0*K1(DIM,3,X1(DIM,3),X2(DIM,3),V1(DIM,3),V2(DIM,3),NDIM,ORD,2,maxnu)+K1(DIM,4,X1(DIM,4),X2(DIM,4),V1(DIM,4),V2(DIM,4),NDIM,ORD,2,maxnu)); 

X2(DIM,1)=X2(DIM,1)+1.D0/6.D0*H*(K2(DIM,1,X1(DIM,1),X2(DIM,1),V1(DIM,1),V2(DIM,1),NDIM,ORD,2,maxnu)+2.D0*K2(DIM,2,X1(DIM,2),X2(DIM,2),V1(DIM,2),V2(DIM,2),NDIM,ORD,2,maxnu)+2.D0*K2(DIM,3,X1(DIM,3),X2(DIM,3),V1(DIM,3),V2(DIM,3),NDIM,ORD,2,maxnu)+K2(DIM,4,X1(DIM,4),X2(DIM,4),V1(DIM,4),V2(DIM,4),NDIM,ORD,2,maxnu)); 

V1(DIM,1)=V1(DIM,1)+1.D0/6.D0*H*(K1(DIM,1,X1(DIM,1),X2(DIM,1),V1(DIM,1),V2(DIM,1),NDIM,ORD,1,maxnu)+2.D0*K1(DIM,2,X1(DIM,2),X2(DIM,2),V1(DIM,2),V2(DIM,2),NDIM,ORD,2,maxnu)+2.D0*K2(DIM,3,X1(DIM,3),X2(DIM,3),V1(DIM,3),V2(DIM,3),NDIM,ORD,2,maxnu)+K2(DIM,4,X1(DIM,4),X2(DIM,4),V1(DIM,4),V2(DIM,4),NDIM,ORD,2,maxnu)); 

V2(DIM,1)=V2(DIM,1)+1.D0/6.D0*H*(K2(DIM,1,X1(DIM,1),X2(DIM,1),V1(DIM,1),V2(DIM,1),NDIM,ORD,1,maxnu)+2.D0*K2(DIM,2,X1(DIM,2),X2(DIM,2),V1(DIM,2),V2(DIM,2),NDIM,ORD,1,maxnu)+2.D0*K2(DIM,3,X1(DIM,3),X2(DIM,3),V1(DIM,3),V2(DIM,3),NDIM,ORD,1,maxnu)+K2(DIM,4,X1(DIM,4),X2(DIM,4),V1(DIM,4),V2(DIM,4),NDIM,ORD,1,maxnu)); 

     _OD; 
     R=((X1(1,5)-X2(1,5))**2.D0+(X1(2,5)-X2(2,5))**2.D0+(X1(3,5)-X2(3,5))**2.D0)**0.5D0; 
      N=N+1; 
write(2,'(A,1i5,6g12.5)')' N,X1(1,1),X1(2,1),X1(3,1),X2(1,1),X2(2,1),X2(3,1):',N,X1(1,1),X1(2,1),X1(3,1),X2(1,1),X2(2,1),X2(1,1),X2(2,1),X2(3,1); 
     _OD; 

END PROGRAM RUNGEKUTT; 

가 나는 기능을 사용하여 뭔가를 이해하지 못하고, 보인다, 도와주세요!

+0

받은 오류 메시지는 인텔 포트란 컴파일러에서 가져온 것이므로 어떤 시점에서 컴파일 할 실제 포트란 코드가 있어야합니다. 뭐라 구요? 전처리 기의 출력은 무엇입니까? Trefor에서 Fortran으로의 확실한 번역을 시도한다면, 아래의 나의 대답은 변함이 없습니다. 함수 K1의 반환 값을 배열로 선언하지만, 배열이 될 수없는 컨텍스트에서 사용합니다 (스칼라에 할당하기 때문에). –

답변

2

스케일러 계산 중입니까? 당신이 무엇을하려하는지 이해한다면,이 함수는 2D 배열을 반환하지만 그것의 한 요소에만 할당합니다. 왜 함수가 배열 대신 스케일러 값을 반환하지 않습니까?

배열 메시지는 표현식에있는 배열 모양 사이의 불일치에 관한 것입니다. 선언을 모두 표시하지 않았으므로 알아낼 수 없습니다.

코딩 스타일 팁 : 0) 오타가 있습니까? Function K1일까요? 1) 세미콜론은 각 행의 끝에서 필요하지 않습니다. Fortran은 C가 아닙니다. 2) 타입, 인 텐트 및 차원에 대한 별도의 줄 대신 각 변수와 관련된 모든 선언을 한 줄에 입력하면 코드가 더 읽기 쉽습니다. 질문의 편집 후

real, dimension (NDIM,ORD), intent (in) :: X1 

편집 : 예를 들어

기계 작성된 코드는 추한입니다.

모든 치수에 대한 계산이 필요합니다. 문제는 어디서입니다. 이 코드는 루프를 포함하는 함수 대신 함수 호출을 포함하는 루프를 보여줍니다. 이 전체적인 디자인을 사용하면 출력 배열의 단일 요소 (즉, 스케일러 변수)를 계산하고 함수가 배열을 반환하는 대신 함수가 반환되게하는 것이 좋습니다. 이 디자인에서는 사용 된 요소가 하나만 포함 된 2D 배열을 반환하는 것은 거의 의미가 없습니다. 그리고 메인 프로그램의 문장이 스케일러를 기대하기 때문에, 컴파일러로부터 에러 메시지를 받는다. 따라서 스케일러를 반환하도록 함수를 다시 설계하십시오.

그리고 배열이 예상 될 때 실제 인수가 단일 요소 인 K1을 호출하는 것처럼 보입니다. 예를 들어 함수에 크기가 X1(NDIM,ORD) 인 배열이 필요한 경우 세 번째 인수로 X1(DIM,i-1)이 있습니다. 이는 실제 (즉, 호출) 및 임시 인수 (즉, 함수)에서 모순되는 문제이기도합니다. K1 함수가 적절한 배열 요소를 선택하는 작업을 수행하려면 전체 배열을 전달해야합니다. 호출이 적절한 배열 요소를 선택하는 것이라면, K1이 배열 대신 스케일러를 입력 인수로 갖도록 다시 작성하십시오. 일관된 디자인이 필요합니다.

+3

3) 의미있는 방식으로 들여 쓰기를하십시오. –

+0

나는 내 게시물을 편집하면서 몇 가지를 명확히하려고 노력한다. – user2654782

+0

나는이 문제를 이해한다고 생각하는데, 당신의 충고에 대해 대단히 감사합니다! 나는 내 무지를 사과한다. 필자는 여전히 Fortran에서 새로운 기능을 사용하지 않았지만, 전반적인 언어 및 프로그래밍 구조 전반을 더 잘 이해하기 위해 많은 노력을 기울이고 있습니다. – user2654782

3

M.S.B. 올바른 방향으로 가고 있지만 문제를 파악하기에 충분하다고 생각합니다. 앞에서 설명한 것처럼 함수 K1은 2 차원 배열을 반환합니다. 그러나 식의 다른 피연산자는 모두 스칼라입니다 (음, H가 무엇인지는 모르지만 문제가되지는 않습니다.) 결국 식은 배열로 평가되고 스칼라는 다음과 같이 확장됩니다. 일치하는 데 필요한. 그런 다음 배열을 스칼라에 할당하면 결국 오류의 원인이됩니다.

나는 당신이 원하는 것을 제안 할 수 있도록 Runge-Kutta와 친숙하지 않습니다. 그러나 함수가 배열이 아닌 스칼라를 반환하기를 원할 수 있습니다.

+0

몇 가지를 명확하게하려고합니다. 내 게시물을 수정합니다. – user2654782

관련 문제