我有一个Fortran 90代码,它在块对角化后找到自旋链哈密顿量的特征值。我生成了每个块的对角化,这似乎工作得很好,直到块的大小变得太大,此时我得到了错误。
spinchain.exe中的0x05E8A247(mkl_avx2.dll)抛出异常:0xC0000005:访问冲突写入位置0x054E8000。
我在Visual Studio 2017中使用带有MKL库的Intel Fortran编译器。从我可以看出,当块矩阵的顺序大于60时,我得到此错误。在Release模式下运行(而不是Debug),代码将一直运行而没有任何抱怨,但我认为输出不正确。
我写了一个简短的代码来创建一个N x N
埃尔米特矩阵并通过zheev例程运行它。为简单起见,我选择了所有1的矩阵,它具有N-1个零特征值和单个特征值N.我只是循环遍历N的值,生成矩阵并用zheev()
对角化,打印N,最大特征值,以及所有特征值的总和。我发现一切都很好,直到N = 51,此时最大特征值返回52然后当我尝试使用错误Critical error detected c0000374
解除分配数组时,我得到一个异常。
点击“继续”,异常变为
Eigtest.exe中0x77A5A879(ntdll.dll)的未处理异常:0xC0000374:堆已损坏(参数:0x77A95910)。
以下代码:
program Eigenvalues
implicit none
integer, parameter :: dp = kind(0.d0)
integer :: N, lwork, info, i
real(dp), allocatable :: lambda(:), work(:), rwork(:)
complex(dp), allocatable :: H(:,:)
do N = 1,70
lwork = 3*N
allocate(H(N,N))
allocate(lambda(N))
allocate(work(lwork))
allocate(rwork(lwork))
H = dcmplx(1.0_dp,0)
call zheev('N','U',N,H,N,lambda,work,lwork,rwork,info)
if (info == 0) then
write(*,'(I5, F16.12, F16.12)'), N, lambda(N), sum(lambda)
else
print*, "diagonalization failed: info = ", info
read*, i
stop
end if
deallocate(H,lambda,work,rwork)
end do
read*, i
end program
我还编写了另一个版本的代码,我将N
作为参数在开头修改并定义了没有allocatable
的数组,它将在没有任何异常的情况下运行,但为N =提供了错误的特征值51和大多数值高于N = 51。
请原谅我,如果我的代码不好,我是物理学家,而不是程序员。意见或建议表示赞赏。
答案 0 :(得分:1)
根据zheev的手册页,数组work
预计为complex*16
,因此我们可能需要类似
real(dp), allocatable :: lambda(:), rwork(:)
complex(dp), allocatable :: H(:,:), work(:)
(这似乎与我的电脑上的gfortran一起工作)。