Loops 在Fortran模块中使用变量时出错
在Fortran模块中使用变量时,我遇到了一个非常奇怪的错误。这是一个非常简单的代码。F的每一列由X的每一列计算得出。X和F都是模块中的变量。下面是代码 在global.f90中:包含X和F的模块声明Loops 在Fortran模块中使用变量时出错,loops,module,fortran,fortran90,intel-fortran,Loops,Module,Fortran,Fortran90,Intel Fortran,在Fortran模块中使用变量时,我遇到了一个非常奇怪的错误。这是一个非常简单的代码。F的每一列由X的每一列计算得出。X和F都是模块中的变量。下面是代码 在global.f90中:包含X和F的模块声明 module global implicit none ! Parameters real(8),parameter :: GravConst = 6.674184D-11 real(8),parameter :: PI = 3.141592653589793D0 integer :: N re
module global
implicit none
! Parameters
real(8),parameter :: GravConst = 6.674184D-11
real(8),parameter :: PI = 3.141592653589793D0
integer :: N
real(8) :: X(3,2)
real(8) :: F(3,2)
real(8) :: omega
real(8) :: density
end module
在main.f90中:计算F
program main
use global
implicit none
integer I,J,K
N = 2
F = 0.0D0
X = 0.0D0
omega = 1.0
density = 0.0
! read positions
open (1,FILE="pos.txt")
do I = 1,N
read(1,*) (X(K,I),K=1,3)
end do
write(*,*) 'X:',(X(J,2),J=1,3)
write(*,*) 'F:',(F(J,2),J=1,3)
write(*,*) 'F(1,2):',omega*omega*X(1,2)- 4.0D0/3.0D0*PI*GravConst*density*X(1,2)
write(*,*) 'F(2,2):',omega*omega*X(2,2)- 4.0D0/3.0D0*PI*GravConst*density*X(2,2)
do I = 1,N
!yorp force
do K = 1,2
F(K,I) = F(K,I) + omega*omega*X(K,I)
end do
!gravity
do K = 1,3
F(K,I) = F(K,I) - 4.0D0/3.0D0*PI*GravConst*density*X(K,I)
end do
end do
write(*,*) (F(J,2),J=1,3)
end
直接计算的F(1,2)和F(2,2)的值在循环前打印。循环结束后,打印F(:,2)的最终值。以下是使用intel/18.0.2的结果。很明显,loop计算的结果是错误的
X: -4.97716000000000 0.897938000000000 -11.4228000000000
F: 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000
F(1,2): -4.97716000000000
F(2,2): 0.897938000000000
-4.69400000000000 -4.97716000000000 0.000000000000000E+000
似乎在循环中发生了一些奇怪的事情。。。但是如果我改变循环中计算的顺序,结果将是正确的
do I = 1,N
!gravity
do K = 1,3
F(K,I) = F(K,I) - 4.0D0/3.0D0*PI*GravConst*density*X(K,I)
end do
!yorp force
do K = 1,2
F(K,I) = F(K,I) + omega*omega*X(K,I)
end do
end do
X: -4.97716000000000 0.897938000000000 -11.4228000000000
F: 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000
F(1,2): -4.97716000000000
F(2,2): 0.897938000000000
-4.97716000000000 0.897938000000000 0.000000000000000E+000
如果我在模块中使用局部变量而不是变量,结果也将是正确的
do I = 1,N
!gravity
do K = 1,3
F(K,I) = F(K,I) - 4.0D0/3.0D0*PI*GravConst*density*X(K,I)
end do
!yorp force
do K = 1,2
F(K,I) = F(K,I) + omega*omega*X(K,I)
end do
end do
X: -4.97716000000000 0.897938000000000 -11.4228000000000
F: 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000
F(1,2): -4.97716000000000
F(2,2): 0.897938000000000
-4.97716000000000 0.897938000000000 0.000000000000000E+000
下面是我使用的pos.txt和makefile
2.64530000 -7.20517000 -4.69400000
-4.97716000 0.89793800 -11.42280000
# Start of the makefile
COMPILER=ifort -O2
DEMBody: global.o main.o
$(COMPILER) -o DEMBody global.o main.o
global.mod: global.o global.f90
$(COMPILER) -c global.f90
global.o: global.f90
$(COMPILER) -c global.f90
main.o: global.mod main.f90
$(COMPILER) -c main.f90
clean:
rm global.mod global.o main.o
# End of the makefile
或者,您可以尝试此输入。这会更清楚
X(1,1) = 1.0
X(2,1) = 2.0
X(3,1) = 3.0
X(1,2) = 4.0
X(2,2) = 5.0
X(3,2) = 6.0
对于“F”,您将得到一个令人困惑的结果:
F(:,1): 1.000 2.000 0.000E+000
F(:,2): 3.000 4.000 0.000E+000
正确的结果应该是
F(:,1): 1.000 2.000 0.000E+000
F(:,2): 4.000 5.000 0.000E+000
似乎X/F的元素被移动了一个单元格。因为“密度”为零,循环的第二部分,重力,实际上是无用的。但如果我们删除此部分,结果将是正确的。我尝试了intel/15.0.6和intel/17.0.7,结果都是正确的。可能与编译器有关?我尝试了-O1而不是-O2,结果是正确的。请提供文件pos.txt使用您在pos.txt中为粒子2提供的位置,我无法复制错误。因为“密度”为零,循环的第二部分重力实际上是无用的。但如果我们删除此部分,结果将是正确的。我尝试了intel/15.0.6和intel/17.0.7,结果都是正确的。可能与编译器有关?我尝试了-O1而不是-O2,结果是正确的。请提供文件pos.txt使用您在pos.txt中为粒子2提供的位置,我无法复制错误。