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)处没有隐式类型。
答案 0 :(得分:5)
这里有很多错误。我们可以指出一些事情,但你将不得不坐下来阅读一本书并学习编程,从较小的程序开始并使它们正确,然后构建。
让我们看一下上面发布的代码中的最后一个例程。我已经改变了一些变量声明的语法,只是为了让它更短,所以一次更适合屏幕。
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
所以你已经使得一个双精度变量,但它也是子程序的名称。那是一个错误;也许你的意思是让这个函数返回一个双精度值;然后你几乎就在那里,你需要将程序标题更改为FUNCTION DERIV(c,u)
- 但你永远不会在任何地方设置派生。所以很可能只是被遗漏了。所以,让我们摆脱那个DOUBLE PRECISION deriv
声明。此外,从未声明使用的L,并且声明不是x的x。
然后你将这两个变量c和u传递给这个子程序,你定义它们是双精度。到目前为止一切顺利,但随后你开始为它们编制索引:例如,c(i)
。因此它们应该是双精度数组,而不仅仅是标量。看看do循环,我猜它们都应该是大小n
- 应该传入,大概是? 。此外,do循环永远不会终止;在end do
之后应该有一个end if
。
此外,您正在使用的^
运算符我假设您正在使用取幂 - 但在Fortran中,那是**
,而不是^
。那个c^(-p)
应该(我猜这里)是c(i)**(-p)
?
最后,你正在设置u(c)
- 但这不是很明智,因为c是一个双精度数字的数组。即使你(c(i))也没有意义 - 你不能用双精度数索引数组。据推测,我只是在这里猜测,你的意思是u
的值对应于c
的刚刚计算的值 - 例如,u(i)
,而不是u(c)
?
因此,鉴于上述情况,我们希望deri子例程看起来像这样:
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左右。让我们试图在整个事情中划分你的意图并相应地重写可能不是任何人的时间的最好用途;你为什么不从这里开始处理一件特别的事情,如果你有特定问题就问另一个问题。