1

二体問題をルンゲクット法で解くプログラムを作成しました。私は問題に直面しました:2次元配列のELEMENTも与える必要がある式から2次元配列のELEMENTを返す関数を呼び出すと(用語と混同して申し訳ありません)、次のメッセージが表示されます:

 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)

この関数の外部インターフェイスがあり、コンパイラがこれを関数と見なしているようです。

いくつかのことを明確にする必要があります。

はい、完全な Fortran ではありません。モスクワ大学の天文学者が使用しているプリプロセッサ Trefor です (私はただの学生です)。この言語は fortran に非常に似ていますが、多くの学生が学習している 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)

つまり、私のコードでは 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;

助けてください、どうやら関数の使い方が分からないようです!

4

2 に答える 2

3

MSB は正しい方向に進んでいますが、ここで問題を解決するには十分だと思います。前述のように、関数 K1 は 2 次元配列を返します。しかし、式の他のすべてのオペランドはスカラーです (まあ、H が何であるかはわかりませんが、おそらく問題ではありません)。結局、式が配列に評価され、スカラーが次のように展開されます。合わせる必要があります。その後、配列をスカラーに割り当てることになり、それがエラーの原因です。

私はルンゲ・クッタに詳しくないので、代わりにあなたが望むものを提案することができません. しかし、関数が配列ではなくスカラーを返すようにしたい場合があります。

于 2013-08-06T01:38:21.753 に答える