2013-08-05 24 views
1

我使用runge-kutt方法创建了一个解决双体问题的程序。我遇到了这个问题:当我调用从表达式返回二维数组的ELEMENT的函数时,它必须给出二维数组的ELEMENT(对于术语造成的混淆),我得到以下消息:错误#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) 

我有这个函数的外部接口,它显然是编译器认为这是一个函数。

我必须澄清一些事情:

是的,这不是很Fortran语言,它的预处理器Trefor,用于在莫斯科大学的天文学家(我只是一个学生)。这种语言与fortran非常相似,但与C语言(例如,分号冒号)有点接近,许多学生对此进行了研究。 Runge-Kutta方法可简要地写为: 我们有初值问题

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) 

iee在我的代码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

您收到的错误消息来自英特尔Fortran编译器,因此在某些时候必须有真正的Fortran代码进行编译。这是什么?预处理器的输出是什么?如果我试图从Trefor到Fortran进行明显的翻译,我下面的答案保持不变。您将函数K1的返回值声明为一个数组,但是您将其用于不允许为数组的上下文中(因为您正在分配给一个标量)。 –

回答

2

你计算一个缩放吗?如果我明白你想要做什么,该函数返回一个二维数组,但你只分配给它的一个元素。为什么不让函数返回一个定标器值而不是数组?

数组消息是关于表达式中的数组形状之间的不一致性。你没有显示所有的声明,所以我们无法弄清楚。

编码风格提示:0)是否有错字?应该是Function K1? 1)每行末尾不需要分号。 Fortran不是C. 2)至少对我而言,如果将与每个变量有关的所有声明放在一行上,而不是单独的行,类型,意图和尺寸,则代码将更具可读性。例如:问题的编辑后

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

编辑:

机器编写的代码是丑陋的。

很明显,您需要对所有维度进行计算。问题在哪里。代码显示包含函数调用的循环,而不是包含循环的函数。通过这种总体设计,计算输出数组的单个元素(即,缩放变量)并使其成为函数返回而不是让函数返回数组是有意义的。对于这种设计,返回仅包含一个使用元素的二维数组是没有意义的。由于您在主程序中的语句需要一个缩放器,因此您会收到来自编译器的错误消息。所以重新设计你的函数返回一个缩放器。

而且它看起来像是在调用K1时实际参数是单个元素,当需要数组时。例如,当函数需要一个大小为X1(NDIM,ORD)的数组时,您有X1(DIM,i-1)作为第三个参数。这也是一个问题,因为实际(即调用)和伪参数(即,函数)中的不一致。如果函数K1要完成选择适当数组元素的工作,则需要将它传递给整个数组。如果调用要选择适当的数组元素,则重写K1以使用缩放器而不是数组作为输入参数。你需要一个一致的设计。

+3

3)以某种有意义的方式缩进。 –

+0

我试图澄清一些事情,编辑我的帖子 – user2654782

+0

我想我明白了这个问题,非常感谢您的建议!我为我的无知道歉。我在Fortran中还是个新手,并没有使用这个函数,我仍然有很多工作来更好地理解语言和编程的总体结构。 – user2654782

3

M.S.B.在正确的轨道上,但我认为这里有足够的解决问题的办法。如上所述,函数K1返回一个二维数组。但是表达式中的所有其他操作数都是标量(好吧,我不知道H是什么,但它可能并不重要。)最终发生的事情是表达式评估为一个数组,标量扩展为需要匹配。然后,您最终将数组分配给标量,这就是错误的原因。

我不够熟悉龙哥库塔能够建议你想要什么。但很可能您希望函数返回一个标量,而不是数组。

+0

我试图澄清一些事情,编辑我的文章 – user2654782