简体   繁体   English

错误#6366:数组表达式的形状不符合

[英]error #6366: The shapes of the array expressions do not conform

I create a program to solve two-body problem by runge-kutt method. 我创建了一个通过runge-kutt方法解决两体问题的程序。 I was faced with the problem: when I call the function which return the ELEMENT of two-dimension array from expression, which must give the ELEMENT of two-dimension array too (sorry for confusion with terms), I get this message: 我遇到了一个问题:当我调用从表达式返回二维数组的ELEMENT的函数时,该函数也必须给出二维数组的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)

I have a external interface for this function and it's apparently that compiler consider this as a function. 我为此功能提供了一个外部接口,显然编译器将此功能视为函数。

I must clarify some things: 我必须澄清一些事情:

Yes, it's not quite Fortran, it's preprocessor Trefor, which is used by astronomers in Moscow University (I'm just a student). 是的,它不是Fortran,而是预处理程序Trefor,莫斯科大学的天文学家都在使用它(我只是一名学生)。 This language is very similar to fortran, but a bit closer to C (Semi-colons for example), which is studied by many students. 该语言与fortran非常相似,但与C(有点像分号)更接近,许多学生都在研究C。 Runge-Kutta method can be briefly written as: We have initial value problem Runge-Kutta方法可以简写为:我们有初值问题

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

y is unknown vector, which contains 12 components in my case (3 coordinates and 3 velocities for each body) y是未知向量,在我的案例中包含12个分量(每个物体3个坐标和3个速度)

next step is 下一步是

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)

Ie in my code X1,2 and V1,2 and K_1,2 should be vectors, because each of them must be have 3 spatial components and 4 components for each 'order' of method. 即在我的代码X1,2和V1,2和K_1,2中应该是向量,因为它们的每个“阶”必须具有3个空间分量和4个分量。 The full code: 完整代码:

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;

Please, help, it seems, I don't understand something in using functions! 请帮忙,看来,我对使用函数不了解!

MSB is on the right track, but I think there's enough here to figure out the problem. MSB处在正确的轨道上,但我认为这里已经足够找出问题所在。 As noted, function K1 returns a two-dimension array. 如前所述,函数K1返回二维数组。 But all of the other operands in the expression are scalars (well, I don't know what H is, but it likely doesn't matter.) What ends up happening is that the expression evaluates to an array, the scalars getting expanded as needed to match up. 但是表达式中的所有其他操作数都是标量(好吧,我不知道H是什么,但是可能没关系。)最终发生的事情是表达式的值是一个数组,标量随着需要配合。 You then end up with assigning an array to a scalar, and that's the cause of the error. 然后,您最终将数组分配给标量,这就是错误的原因。

I am not familiar enough with Runge-Kutta to be able to suggest what you want instead. 我对Runge-Kutta不够熟悉,无法提出您想要的建议。 But it is likely that you want the function to return a scalar, not an array. 但是您可能希望函数返回标量,而不是数组。

Are you calculating a scaler? 您正在计算洁牙机吗? If I understand what you are trying to do, the function returns a 2D array, but you only assign to one element of it. 如果我了解您要执行的操作,该函数将返回一个2D数组,但是您只能分配给它的一个元素。 Why not have the function return a scaler value instead of an array? 为什么不让该函数返回缩放器值而不是数组?

The array message is about an inconsistency between the shapes of arrays in the expression. 数组消息涉及表达式中数组形状之间的不一致。 You haven't shown all of the declarations so we can't figure that out. 您尚未显示所有声明,因此我们无法弄清楚。

Coding style tips: 0) Is there a typo? 编码样式提示:0)是否有错字? Should it be Function K1 ? 应该是Function K1吗? 1) Semi-colons aren't necessary on the end of each line. 1)每行的末尾不需要分号。 Fortran isn't C. 2) At least to me, your code would be more readable if you put all of the declarations pertaining to each variable on one line, instead of separate lines for type, intent and dimension. Fortran不是C。2)至少对我来说,如果将与每个变量相关的所有声明放在一行上,而不是在类型,意图和维度上单独一行,则代码将更具可读性。 For example: 例如:

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

EDIT after the edit of the question: 编辑问题后进行编辑:

The machine written code is ugly. 机器编写的代码很难看。

It is clear that you need to do the calculation for all the dimensions. 显然,您需要对所有尺寸进行计算。 The question is where. 问题是在哪里。 The code shows the loops containing the function call rather than the function containing the loops. 该代码显示了包含函数调用的循环,而不是包含循环的函数。 With this overall design it would make sense that you calculate a single element of the output array (ie, a scaler variable) and have that be the function return instead of having the function return an array. 通过这种总体设计,有意义的是您计算输出数组的单个元素(即缩放器变量),并将其作为函数返回,而不是让函数返回数组。 For this design, it makes little sense to return a 2D array containing only a single used element. 对于此设计,返回仅包含一个已使用元素的2D数组几乎没有意义。 And since your statement in the main program expects a scaler, you are getting the error message from the compiler. 并且由于主程序中的语句需要定标器,因此您从编译器获取错误消息。 So redesign your function to return a scaler. 因此,请重新设计函数以返回缩放器。

And it looks that you are calling K1 with the actual argument being single elements when arrays are expected. 并且看起来您在调用K1时,实际参数是期望数组时的单个元素。 For example, you have X1(DIM,i-1) as a third argument when the function expects an array of size X1(NDIM,ORD) . 例如,当函数期望数组大小为X1(NDIM,ORD)时,将X1(DIM,i-1)作为第三个参数。 This also a problem, as an inconsistency in actual (ie, call) and dummy arguments (ie, function). 这也是一个问题,因为实际参数(即调用)和伪参数(即函数)不一致。 If function K1 is to do the work of selecting the appropriate array elements, you need to pass it the entire array. 如果功能K1负责选择适当的数组元素,则需要将整个数组传递给它。 If the call is to select the appropriate array elements, then rewrite K1 to have scalers instead of arrays as input arguments. 如果调用是为了选择适当的数组元素,则重写K1以使用缩放器而不是数组作为输入参数。 You need a consistent design. 您需要一致的设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM