我的代码中只剩下一个错误,
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里有很多错误。我们可以指出其中一些事情,但是您必须坐下来阅读一本书并学习编程,从较小的程序开始并使其正确,然后进行构建。
让我们看看上面发布的代码中的最后一个例程。我更改了一些变量声明的语法,只是为了使其更短,以便更适合屏幕。
因此,您已将 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 子例程如下所示:
请注意,在现代 fortran 中,do 循环可以用 where 语句替换,并且您也不需要显式传递大小;这样你就可以得到更清晰和更短的结果:
但请注意,我已经不得不猜测你在这部分代码中的含义三倍了,而这大约只占代码总数的 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.
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 thatDOUBLE 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 sizen
-- which should be passed in, presumably? . Also, the do loop is never terminated; there should be anend do
after theend if
.Further, the
^
operator you're using I'm assuming you're using for exponentiation -- but in Fortran, that's**
, not^
. And thatc^(-p)
should (I'm guessing here) bec(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 ofu
corresponding to the just-calculated value ofc
-- eg,u(i)
, notu(c)
?So given the above, we'd expect the deriv subroutine to look like this:
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:
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.