我的代码中只剩下一个错误,

发布于 2024-11-03 08:09:46 字数 3263 浏览 1 评论 0原文

PROGRAM MPI
IMPLICIT NONE
INTEGER, PARAMETER :: nn=100

DOUBLE PRECISION h, L
DOUBLE PRECISION, DIMENSION (2*nn) :: y, ynew
DOUBLE PRECISION, DIMENSION (nn) :: qnew,vnew
DOUBLE PRECISION, DIMENSION (2*nn) :: k1,k2,k3,k4
INTEGER j, k
INTEGER i
INTEGER n

n=100 !particles
L=2.0d0
h=1.0d0/n
y(1)=1.0d0

DO k=1,2*n          ! time loop

   CALL RHS(y,k1)
   CALL RHS(y+(h/2.0d0)*k1,k2)
   CALL RHS(y+(h/2.0d0)*k2,k3)
   CALL RHS(y+h*k3,k4)

   ynew(1:2*n)=y(1:2*n) + (k1 + 2.0d0*(k2 + k3) + k4)*h/6.0d0
END DO
         qnew(1:n)=ynew(1:n)
    vnew(1:n)=ynew(n+1:2*n)

    DO i=1,n
       IF (qnew(i).GT. L) THEN
       qnew(i) = qnew(i) - L
       ENDIF
    END DO

     write(*,*) 'qnew=', qnew(1:n)
     write(*,*) 'vnew=', vnew(1:n)

     END PROGRAM MPI

    !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    !   Right hand side of the ODE
    !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
             SUBROUTINE RHS(y,z)

             IMPLICIT NONE
             INTEGER, PARAMETER :: nn=100
             DOUBLE PRECISION, DIMENSION (2*nn) :: y
             DOUBLE PRECISION, DIMENSION (2*nn) :: z
             DOUBLE PRECISION, DIMENSION (nn) :: F
             DOUBLE PRECISION, DIMENSION (nn) :: g
             INTEGER n
             INTEGER m
             n=100
             m=1/n

     z(1:n)=y(n+1:2*n)
     CAll FORCE(g,F)
     z(n+1:2*n)=F(1:n)/m

             RETURN
             END
     !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     !      Force acting on each particle
     !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

              SUBROUTINE FORCE(g,F)

                         IMPLICIT NONE

                INTEGER, PARAMETER :: nn=100
                DOUBLE PRECISION, DIMENSION (nn) :: F
                DOUBLE PRECISION, DIMENSION (nn) :: q
                DOUBLE PRECISION, DIMENSION (nn) :: g
                DOUBLE PRECISION u
                INTEGER j, e
                INTEGER n
                n=100
                e=1/n

                DO j=2,n+1

                 CALL deriv((abs(q(j)-q(j-1)))/e,u)
                 g(j-1)=((y(j)-y(j-1))/(abs(y(j)-y(j-1))))*u
                 CALL deriv((abs(q(j)-q(j+1)))/e,u)
                 g(j+1)=((y(j)-y(j+1))/(abs(y(j)-y(j+1))))*u

                 F(j)=g(j-1)+g(j+1)

                END DO
              RETURN
              END

              SUBROUTINE deriv(c,u,n)

                         IMPLICIT NONE

                INTEGER, INTENT(in) :: n
                DOUBLE PRECISION, DIMENSION(n), INTENT(IN) :: c
                DOUBLE PRECISION, DIMENSION(n), INTENT(OUT) :: u
                INTEGER, PARAMETER :: p=2
                INTEGER, PARAMETER :: cr=100
                INTEGER :: i
                DOUBLE PRECISION L
                L=2.0d0

                DO i= 1,n
                      IF  (c(i) .LE. L) THEN
                          u(i)=cr*(L*(c(i)**(-p))-L**(1-p))
                      ELSE IF (c(i) .GT. L)  THEN
                           u(i)=0
                      END IF

                END DO

             RETURN
             END SUBROUTINE deriv

我只在第 85 行和第 87 行收到一个相同的错误。它说:

y 在 y(j-1) 和 y(j+1) 处没有隐式类型。

PROGRAM MPI
IMPLICIT NONE
INTEGER, PARAMETER :: nn=100

DOUBLE PRECISION h, L
DOUBLE PRECISION, DIMENSION (2*nn) :: y, ynew
DOUBLE PRECISION, DIMENSION (nn) :: qnew,vnew
DOUBLE PRECISION, DIMENSION (2*nn) :: k1,k2,k3,k4
INTEGER j, k
INTEGER i
INTEGER n

n=100 !particles
L=2.0d0
h=1.0d0/n
y(1)=1.0d0

DO k=1,2*n          ! time loop

   CALL RHS(y,k1)
   CALL RHS(y+(h/2.0d0)*k1,k2)
   CALL RHS(y+(h/2.0d0)*k2,k3)
   CALL RHS(y+h*k3,k4)

   ynew(1:2*n)=y(1:2*n) + (k1 + 2.0d0*(k2 + k3) + k4)*h/6.0d0
END DO
         qnew(1:n)=ynew(1:n)
    vnew(1:n)=ynew(n+1:2*n)

    DO i=1,n
       IF (qnew(i).GT. L) THEN
       qnew(i) = qnew(i) - L
       ENDIF
    END DO

     write(*,*) 'qnew=', qnew(1:n)
     write(*,*) 'vnew=', vnew(1:n)

     END PROGRAM MPI

    !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    !   Right hand side of the ODE
    !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
             SUBROUTINE RHS(y,z)

             IMPLICIT NONE
             INTEGER, PARAMETER :: nn=100
             DOUBLE PRECISION, DIMENSION (2*nn) :: y
             DOUBLE PRECISION, DIMENSION (2*nn) :: z
             DOUBLE PRECISION, DIMENSION (nn) :: F
             DOUBLE PRECISION, DIMENSION (nn) :: g
             INTEGER n
             INTEGER m
             n=100
             m=1/n

     z(1:n)=y(n+1:2*n)
     CAll FORCE(g,F)
     z(n+1:2*n)=F(1:n)/m

             RETURN
             END
     !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     !      Force acting on each particle
     !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

              SUBROUTINE FORCE(g,F)

                         IMPLICIT NONE

                INTEGER, PARAMETER :: nn=100
                DOUBLE PRECISION, DIMENSION (nn) :: F
                DOUBLE PRECISION, DIMENSION (nn) :: q
                DOUBLE PRECISION, DIMENSION (nn) :: g
                DOUBLE PRECISION u
                INTEGER j, e
                INTEGER n
                n=100
                e=1/n

                DO j=2,n+1

                 CALL deriv((abs(q(j)-q(j-1)))/e,u)
                 g(j-1)=((y(j)-y(j-1))/(abs(y(j)-y(j-1))))*u
                 CALL deriv((abs(q(j)-q(j+1)))/e,u)
                 g(j+1)=((y(j)-y(j+1))/(abs(y(j)-y(j+1))))*u

                 F(j)=g(j-1)+g(j+1)

                END DO
              RETURN
              END

              SUBROUTINE deriv(c,u,n)

                         IMPLICIT NONE

                INTEGER, INTENT(in) :: n
                DOUBLE PRECISION, DIMENSION(n), INTENT(IN) :: c
                DOUBLE PRECISION, DIMENSION(n), INTENT(OUT) :: u
                INTEGER, PARAMETER :: p=2
                INTEGER, PARAMETER :: cr=100
                INTEGER :: i
                DOUBLE PRECISION L
                L=2.0d0

                DO i= 1,n
                      IF  (c(i) .LE. L) THEN
                          u(i)=cr*(L*(c(i)**(-p))-L**(1-p))
                      ELSE IF (c(i) .GT. L)  THEN
                           u(i)=0
                      END IF

                END DO

             RETURN
             END SUBROUTINE deriv

I am only getting one same error on line 85 and 87. It says:

y has no implicit type at y(j-1) ans at y(j+1).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暖心男生 2024-11-10 08:09:46

这里有很多错误。我们可以指出其中一些事情,但是您必须坐下来阅读一本书并学习编程,从较小的程序开始并使其正确,然后进行构建。

让我们看看上面发布的代码中的最后一个例程。我更改了一些变量声明的语法,只是为了使其更短,以便更适合屏幕。

 SUBROUTINE deriv(c,u)
 IMPLICIT NONE
 DOUBLE PRECISION :: deriv, c, u
 INTEGER :: p, x, cr, n

 L=2.0d0
 cr=100
 p=2
 n=100

 DO i= 1,n
 IF  (c(i).LE. L) THEN
     u(c)=cr*(L*c^(-p)-L^(1-p))
     ELSE IF (c(i) .GT. L)  THEN
     u(c)=0
 END IF

 RETURN
 END

因此,您已将 deriv 设置为双精度变量,但它也是子例程的名称。这是一个错误;也许您打算使其成为一个返回双精度值的函数;那么您就快到了,您需要将过程标头更改为 FUNCTION DERIV(c,u) ——但您从未在任何地方设置 deriv 。因此很可能应该将其排除在外。因此,让我们删除该 DOUBLE PRECISION deriv 声明。另外,L(已使用)从未声明,而 x(未使用)则已声明。

然后向该子例程传递两个变量 c 和 u,将其定义为双精度。到目前为止一切顺利,但随后您开始对它们建立索引:例如,c(i)。所以它们应该是双精度数组,而不仅仅是标量。看看 do 循环,我猜它们的大小都应该是 n ——大概应该传入? 。此外,do 循环永远不会终止; end if 之后应该有一个 end do

此外,您使用的 ^ 运算符我假设您用于求幂 - 但在 Fortran 中,这是 **,而不是 ^.那 c^(-p) 应该(我在这里猜测)是 c(i)**(-p) 吗?

最后,您要设置 u(c) ——但这不是很明智,因为 c 是一个双精度数字数组。即使 u(c(i)) 也没有意义——你不能用双精度数字索引数组。据推测,我只是在这里猜测,您的意思是 u 的值对应于刚刚计算的 c 值 - 例如,u(i),不是u(c)

因此,考虑到上述情况,我们期望 deriv 子例程如下所示:

 SUBROUTINE deriv(c,u,n)
 IMPLICIT NONE
 INTEGER, INTENT(in) :: n
 DOUBLE PRECISION, DIMENSION(n), intent(IN) :: c
 DOUBLE PRECISION, DIMENSION(n), intent(OUT) :: u

 INTEGER, PARAMETER :: p=2, cr=100
 DOUBLE PRECISION, PARAMETER :: L=2.0
 INTEGER :: i

 DO i= 1,n
     IF  (c(i) .LE. L) THEN
         u(i)=cr*(L*c(i)**(-p)-L**(1-p))
     ELSE IF (c(i) .GT. L)  THEN
         u(i)=0
     END IF
 END DO

 RETURN
 END SUBROUTINE deriv

请注意,在现代 fortran 中,do 循环可以用 where 语句替换,并且您也不需要显式传递大小;这样你就可以得到更清晰和更短的结果:

 SUBROUTINE DERIV(c,u)
 IMPLICIT NONE
 DOUBLE PRECISION, DIMENSION(:), intent(IN) :: c
 DOUBLE PRECISION, DIMENSION(size(c,1)), intent(OUT) :: u

 INTEGER, PARAMETER :: p=2, cr=100
 DOUBLE PRECISION, PARAMETER :: L=2.0

 WHERE (c <= L)
     u=cr*(L*c**(-p)-L**(1-p))
 ELSEWHERE
     u=0
 ENDWHERE

 RETURN
 END SUBROUTINE DERIV

但请注意,我已经不得不猜测你在这部分代码中的含义三倍了,而这大约只占代码总数的 1/4。让我们尝试猜测您在整个事情中的意图并相应地重写可能不是对任何人时间的最佳利用;如果您遇到特定问题,为什么不从这里开始处理一件特定的事情并提出另一个问题。

There's a lot wrong here. We can point out some of the things, but you're going to have to sit down with a book and learn about programming, starting with smaller programs and getting them right, then building up.

Let's look at the last routine in the code you posted above. I've changed the syntax of some of the variable declarations just to make it shorter so more fits on screen at once.

 SUBROUTINE deriv(c,u)
 IMPLICIT NONE
 DOUBLE PRECISION :: deriv, c, u
 INTEGER :: p, x, cr, n

 L=2.0d0
 cr=100
 p=2
 n=100

 DO i= 1,n
 IF  (c(i).LE. L) THEN
     u(c)=cr*(L*c^(-p)-L^(1-p))
     ELSE IF (c(i) .GT. L)  THEN
     u(c)=0
 END IF

 RETURN
 END

So you've made deriv a double precision variable, but it's also the name of the subroutine. That's an error; maybe you meant to make this a function which returns a double precision value; then you're almost there, you'd need to change the procedure header to FUNCTION DERIV(c,u) -- but you never set deriv anywhere. So likely that should just be left out. So let's just get rid of that DOUBLE PRECISION deriv declaration. Also, L, which is used, is never declared, and x, which isn't, is declared.

Then you pass in to this subroutine two variables, c and u, which you define to be double precision. So far so good, but then you start indexing them: eg, c(i). So they should be arrays of double precisions, not just scalars. Looking at the do loop, I'm guessing they should both be of size n -- which should be passed in, presumably? . Also, the do loop is never terminated; there should be an end do after the end if.

Further, the ^ operator you're using I'm assuming you're using for exponentiation -- but in Fortran, that's **, not ^. And that c^(-p) should (I'm guessing here) be c(i)**(-p)?

Finally, you're setting u(c) -- but that's not very sensible, as c is an array of double precision numbers. Even u(c(i)) wouldn't make sense -- you can't index an array with a double precision number. Presumably, and I'm just guessing here, you mean the value of u corresponding to the just-calculated value of c -- eg, u(i), not u(c)?

So given the above, we'd expect the deriv subroutine to look like this:

 SUBROUTINE deriv(c,u,n)
 IMPLICIT NONE
 INTEGER, INTENT(in) :: n
 DOUBLE PRECISION, DIMENSION(n), intent(IN) :: c
 DOUBLE PRECISION, DIMENSION(n), intent(OUT) :: u

 INTEGER, PARAMETER :: p=2, cr=100
 DOUBLE PRECISION, PARAMETER :: L=2.0
 INTEGER :: i

 DO i= 1,n
     IF  (c(i) .LE. L) THEN
         u(i)=cr*(L*c(i)**(-p)-L**(1-p))
     ELSE IF (c(i) .GT. L)  THEN
         u(i)=0
     END IF
 END DO

 RETURN
 END SUBROUTINE deriv

Note that in modern fortran, the do loop can be replaced with a where statement, and also you don't need to explicitly pass in the size; so then you could get away with the clearer and shorter:

 SUBROUTINE DERIV(c,u)
 IMPLICIT NONE
 DOUBLE PRECISION, DIMENSION(:), intent(IN) :: c
 DOUBLE PRECISION, DIMENSION(size(c,1)), intent(OUT) :: u

 INTEGER, PARAMETER :: p=2, cr=100
 DOUBLE PRECISION, PARAMETER :: L=2.0

 WHERE (c <= L)
     u=cr*(L*c**(-p)-L**(1-p))
 ELSEWHERE
     u=0
 ENDWHERE

 RETURN
 END SUBROUTINE DERIV

But notice that I've already had to guess three times what you meant in this section of code, and this is only about 1/4th of the total of the code. Having us try to divine your intention in the whole thing and rewrite accordingly probably isn't the best use of anyone's time; why don't you proceed from here working on one particular thing and ask another question if you have a specific problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文