Fortran:二维数组取值未分配
Fortran: 2D array taking value not assigned
我正在创建一个二维数组 phi
并将其初始化为 0。然后我将通过一对 do 循环来修改 phi
的一些值。但是,有些值在不应该分配的时候被分配了。
特别是当我 运行 下面的示例(用 ifort 14 或 15 编译)时,底行的大约 1/3 是 -20
,当我用 gfortran 编译时,大约有 1/3最下面一行是 -20
,另外 1/3 是 10
.
当我取消注释 if-elseif
语句之前的 phi(i,j) = 0.0
时,phi(i,j)
的值保持 0.0
。所以这并不是说 if-elseif
正在改变它的值。
有人知道这是什么原因吗?
作为附带问题,当我取消注释 close (42)
时,我在它后面放置的任何内容都不会执行。所以我不确定这是否相关。
谢谢,
约翰
program test
implicit none
real, parameter, dimension(2) :: delta = (/ 1E-7, 1E-7 /)
real,parameter,dimension(2) :: Length = (/ 6E-6, 5E-6 /)
integer, PARAMETER, dimension(2) :: cells = Length / delta
real, dimension(cells(1), cells(2)) :: phi
REAL,parameter :: V0 = -20
REAL,parameter :: VL = 10
integer :: i,j
phi = 0.0
open(unit=42,file='ChangeValuePhi.csv',form='formatted')
do i = 0, size(phi,1)
do j = 0, size(phi,2)
if (j .ne. 0) then
write(42,'(A)',Advance="NO") ","
endif
! phi(i,j) = 0.0
if (j <= nint(lowerBoundary(i * delta(1)) / delta(2))) then !If at minimum z feature
phi(i,j) = V0
elseif (j >= nint(upperBoundary(i * delta(1)) / delta(2))) then !If at maximum z feature
phi(i,j) = VL
end if
write(42,'(F6.2)',Advance="NO") phi(i,j)
enddo
write(42,*)
enddo
!close(42)
contains
function lowerBoundary(r) result(z)
real :: r,z
real, parameter :: RL = 3E-6
real, parameter :: HL = 3E-6
if (r < RL) then
z = HL - HL * (r / RL)
elseif (r >= RL) then
z = 0.0
endif
end function lowerBoundary
function upperBoundary(r) result(z)
real :: r,z
real, parameter :: RU = 0.0
real, parameter :: HU = 0.0
if (r <= RU) then
z = Length(2) - (HU - HU * (r / RU))
elseif (r > RU) then
z = Length(2) - 0.0
end if
end function upperBoundary
end program test
您正在 phi
越界访问。在你的循环中,
do i = 0, size(phi,1)
do j = 0, size(phi,2)
...
! phi(i,j) = 0.0
if (j <= nint(lowerBoundary(i * delta(1)) / delta(2))) then !If at minimum z feature
phi(i,j) = V0
elseif (j >= nint(upperBoundary(i * delta(1)) / delta(2))) then !If at maximum z feature
phi(i,j) = VL
end if
...
enddo
您正在使用等于 0 的 i
或 j
访问 phi
。Fortran 数组是从 1 开始索引的,除非您明确声明下限是其他值(例如 0 ).您看到的不正确输出是由于越界访问造成的。
您可以将 do 循环的开头更改为
do i = 1, size(phi,1)
do j = 1, size(phi,2)
if (j .ne. 1) then
write(42,'(A)',Advance="NO") ","
endif
避免越界访问。
我正在创建一个二维数组 phi
并将其初始化为 0。然后我将通过一对 do 循环来修改 phi
的一些值。但是,有些值在不应该分配的时候被分配了。
特别是当我 运行 下面的示例(用 ifort 14 或 15 编译)时,底行的大约 1/3 是 -20
,当我用 gfortran 编译时,大约有 1/3最下面一行是 -20
,另外 1/3 是 10
.
当我取消注释 if-elseif
语句之前的 phi(i,j) = 0.0
时,phi(i,j)
的值保持 0.0
。所以这并不是说 if-elseif
正在改变它的值。
有人知道这是什么原因吗?
作为附带问题,当我取消注释 close (42)
时,我在它后面放置的任何内容都不会执行。所以我不确定这是否相关。
谢谢,
约翰
program test
implicit none
real, parameter, dimension(2) :: delta = (/ 1E-7, 1E-7 /)
real,parameter,dimension(2) :: Length = (/ 6E-6, 5E-6 /)
integer, PARAMETER, dimension(2) :: cells = Length / delta
real, dimension(cells(1), cells(2)) :: phi
REAL,parameter :: V0 = -20
REAL,parameter :: VL = 10
integer :: i,j
phi = 0.0
open(unit=42,file='ChangeValuePhi.csv',form='formatted')
do i = 0, size(phi,1)
do j = 0, size(phi,2)
if (j .ne. 0) then
write(42,'(A)',Advance="NO") ","
endif
! phi(i,j) = 0.0
if (j <= nint(lowerBoundary(i * delta(1)) / delta(2))) then !If at minimum z feature
phi(i,j) = V0
elseif (j >= nint(upperBoundary(i * delta(1)) / delta(2))) then !If at maximum z feature
phi(i,j) = VL
end if
write(42,'(F6.2)',Advance="NO") phi(i,j)
enddo
write(42,*)
enddo
!close(42)
contains
function lowerBoundary(r) result(z)
real :: r,z
real, parameter :: RL = 3E-6
real, parameter :: HL = 3E-6
if (r < RL) then
z = HL - HL * (r / RL)
elseif (r >= RL) then
z = 0.0
endif
end function lowerBoundary
function upperBoundary(r) result(z)
real :: r,z
real, parameter :: RU = 0.0
real, parameter :: HU = 0.0
if (r <= RU) then
z = Length(2) - (HU - HU * (r / RU))
elseif (r > RU) then
z = Length(2) - 0.0
end if
end function upperBoundary
end program test
您正在 phi
越界访问。在你的循环中,
do i = 0, size(phi,1)
do j = 0, size(phi,2)
...
! phi(i,j) = 0.0
if (j <= nint(lowerBoundary(i * delta(1)) / delta(2))) then !If at minimum z feature
phi(i,j) = V0
elseif (j >= nint(upperBoundary(i * delta(1)) / delta(2))) then !If at maximum z feature
phi(i,j) = VL
end if
...
enddo
您正在使用等于 0 的 i
或 j
访问 phi
。Fortran 数组是从 1 开始索引的,除非您明确声明下限是其他值(例如 0 ).您看到的不正确输出是由于越界访问造成的。
您可以将 do 循环的开头更改为
do i = 1, size(phi,1)
do j = 1, size(phi,2)
if (j .ne. 1) then
write(42,'(A)',Advance="NO") ","
endif
避免越界访问。