修改代码之后我的图变成这样了,为什么

Created on: October 11, 2025

Answered using GPT-5 Thinking by Chat01

Question

截屏2025-10-11 09.47.19.png截屏2025-10-11 09.47.19.png

修改代码之后我的图变成这样了,为什么

Python

python
list(os.listdir('/mnt/data'))[:50] ['截屏2025-10-11 11.58.02.png', 'RPA5.for', '截屏2025-10-11 09.47.19.png']

Python

python
with open('/mnt/data/RPA5.for','rb') as f: head=f.read(4000) head[:2000] b' module para_meter\r\n\timplicit none\r\n\tinteger l,n,nn,m\r\n\treal(8) pi,u1,u(4,4),mu,e,t1,t2,beta,eps\r\n\tparameter(l=100,n=l*l,nn=n*2,m=240,e=0.001)\r\n\treal(8) ek(l,l,2),nf(l,l,2)\r\n\tcomplex(8) unit(l,l,2,2),ii\r\n\tparameter(ii=(0.d0,1.d0),pi=3.1415926535897932384626d0,u1=0.1d0)\r\n\tparameter (t1=1.d0,t2=-0.2d0,beta=3.d3,eps=1.d-8)\r\n\tend module\r\n\r\n\tprogram main\r\n\tuse para_meter\r\n\timplicit none\r\n\tinteger i,j,k,iu,iv,ia,ix,iy,jx,jy,matz,ierr,ik,iq\r\n integer ipvt(4),job,info,row,column,mode,count,countk\r\n\treal(8) w(2),sgn,phi(m),v(m,m),gap(m,m),gapsymmetry(m),wg(m)\r\n\treal(8) zr(2,2),zi(2,2),fv1(2),fv2(2),fm1(2,2),hr(2,2),hi(2,2)\r\n\treal(8) px,py,sigmad(2,2),is(2,2),ran,gapfunction(l,l)\r\n\treal(8) wm(2),zrm(2,2),zim(2,2),fv1mag(2),fv2mag(2),fm1mag(2,2)\r\n\tcomplex(8) det(2),work(4),gamma(2,2,2,2,l,l,2),hk(2,2)\r\n\tcomplex(8) chi(2,2,2,2,l,l),chi_0(4,4),chi_c(4,4),chi_s(4,4)\r\n\tcomplex(8) chi_u(4,4),chi_uc(4,4),chi_us(4,4),mag(2,2),zm(2,2)\r\n\tinteger l1,l2,l12,l3,l4,l34,p,q,s,r,pq,sr,pr,qs,ps,qr,a,b\r\n\tinteger qx,qy,qx_,qy_,kx,ky,ikx(m),iky(m),ika(m),qx1,qy1\r\n\tlogical logic1,logic2,logic3,logic4\r\n\t\r\n\treal(8) chi0_real(4,4), chi0_imag(4,4), w0(4), zr0(4,4), zi0(4,4)\r\n\treal(8) fv10(4), fv20(4), fm10(4,4), w0_max\r\n\tinteger ierr0\r\n\r\n\tcomplex(8) mag0(2,2)\r\n\treal(8) mag0_real(2,2), mag0_imag(2,2)\r\n\treal(8) w2(2), zr2(2,2), zi2(2,2), fv12(2), fv22(2), fm12(2,2)\r\n\r\n\topen(1,file="hopping.dat")\r\n\topen(2,file="check.dat")\r\n\topen(3,file="k_point.dat")\r\n\topen(6,file="eigen_value.dat")\r\n\topen(4,file="gap_1.dat")\r\n\topen(5,file="gap_2.dat")\r\n\topen(13,file="gap_3.dat")\r\n\topen(14,file="gap_4.dat")\r\n\topen(15,file="gap_5.dat")\r\n\topen(16,file="gap_6.dat")\r\n\topen(17,file="gap_7.dat")\r\n\topen(18,file="gap_8.dat")\r\n\topen(19,file="gap_9.dat")\r\n\topen(20,file="gap_10.dat")\r\n\topen(111,file="gap_11.dat")\r\n\topen(112,file="gap_12.dat")\r\n\topen(113,file="gap_13.dat")\r\n\topen(114,file="gap_14.dat")\r\n\topen(115,file="gap_15.dat")\r\n\topen(116,file="gap_16.dat")\r\n\topen(117,file="gap_17.dat")\r\n\topen(118,file="gap_18.da'

Python

python
with open('/mnt/data/RPA5.for','r',encoding='latin-1',errors='ignore') as f: content=f.read() print(len(content)) print(content.splitlines()[:40])

Python

python
import re def grep(pattern): lines=content.splitlines() hits=[] for i,l in enumerate(lines,1): if re.search(pattern,l,re.I): hits.append((i,l[:200])) return hits[:50] grep('chi')[:20] [(22, '\tcomplex(8) chi(2,2,2,2,l,l),chi_0(4,4),chi_c(4,4),chi_s(4,4)'), (23, '\tcomplex(8) chi_u(4,4),chi_uc(4,4),chi_us(4,4),mag(2,2),zm(2,2)'), (28, '\treal(8) chi0_real(4,4), chi0_imag(4,4), w0(4), zr0(4,4), zi0(4,4)'), (143, '\tchi(l1,l2,l3,l4,qx,qy)=0.d0'), (148, ' chi(l1,l2,l3,l4,qx,qy)=chi(l1,l2,l3,l4,qx,qy)+unit(kx,ky,l4,a)'), (157, '\tchi(l1,l2,l3,l4,qx_,qy_)=dconjg(chi(l1,l2,l3,l4,qx,qy))'), (158, '\tchi(l3,l4,l1,l2,qx,qy)=dconjg(chi(l1,l2,l3,l4,qx,qy))'), (159, '\tchi(l3,l4,l1,l2,qx_,qy_)=chi(l1,l2,l3,l4,qx,qy)'), (175, '\tchi_0(l12,l34)=chi(l1,l2,l3,l4,qx,qy)'), (182, 'c 计ç®\x97é\x9d\x9eç\x9b¸äº\x92ä½\x9cç\x94¨ç£\x81å\x8c\x96ç\x8e\x87 chi_0 ç\x9a\x84æ\x9c\x80大æ\x9c¬å¾\x81å\x80¼'), (185, ' \tchi0_real(i,j) = dreal(chi_0(i,j))'), (186, ' \tchi0_imag(i,j) = dimag(chi_0(i,j))'), (191, 'c \tcall ch(4,4,chi0_real,chi0_imag,w0,matz,zr0,zi0,fv10,fv20,fm10,ierr)'), (198, 'c! ---- ç\x94¨ chi_0 æ\x9e\x84é\x80\xa0 2Ã\x972 轨é\x81\x93ç£\x81å\x8c\x96ç\x8e\x87ç\x9f©é\x98µï¼\x88é\x9d\x9eç\x9b¸äº\x92ä½\x9cç\x94¨æ\x9e\x81é\x99\x90ï¼\x89----'), (200, 'c ç\x94± 4x4 ç\x9a\x84 chi_0 å\x8f\x96å\x87ºè½¨é\x81\x93(11,22)å\xad\x90å\x9d\x97ï¼\x8cç»\x84æ\x88\x90 2x2 ç\x9a\x84é\x9d\x9eç\x9b¸äº\x92ä½\x9cç\x94¨è\x87ªæ\x97\x8bç£\x81å\x8c\x96ç\x8e\x87 ==='), (201, ' mag0(1,1) = chi_0(1,1) '), (202, ' mag0(1,2) = chi_0(1,4) '), (203, ' mag0(2,1) = chi_0(4,1) '), (204, ' mag0(2,2) = chi_0(4,4) '), (230, '\tchi_uc(i,j)=0.d0')]

Python

python
lines=content.splitlines() for i in range(170,215): print(i+1, lines[i][:200])

Python

python
for i in range(215,260): print(i+1, lines[i][:200])

Python

python
grep('open\\(37') [(76, '\topen(37,file="sus0.dat")')]

Python

python
for i in range(60,90): print(i+1,lines[i][:200])

Python

python
grep('write\\(')[:40] [(114, '\twrite(3,*)px,py'), (130, '\twrite(*,*)"doping=",count*2.d0/nn'), (131, '\twrite(*,*)"k-point number=",countk'), (226, ' write(37,*) px - py/2.d0, py * dsqrt(3.d0)/2.d0, -w0_max'), (290, '\twrite(30,*)qx1,qy1,-dreal(chi_s(1,1))'), (291, '\twrite(40,*)qx1,qy1,-dreal(chi_s(2,3))'), (292, '\twrite(50,*)qx1,qy1,-dreal(chi_s(3,2))'), (293, '\twrite(60,*)qx1,qy1,-dreal(chi_s(4,4))'), (307, '\twrite(35,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0, -wm(1)'), (309, '\twrite(36,*)qx1,qy1,zm(1,1),zm(2,1)'), (396, '\twrite(*,*)i,wg(i)/(n*2*e)'), (397, '\twrite(6,*)i,wg(i)/(n*2*e)'), (412, '\twrite(4,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (427, '\twrite(5,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (442, '\twrite(13,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (457, '\twrite(14,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (472, '\twrite(15,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (487, '\twrite(16,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (504, '\twrite(17,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (519, '\twrite(18,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (535, '\twrite(19,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (550, '\twrite(20,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (566, '\twrite(111,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (581, '\twrite(112,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (596, '\twrite(113,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (611, '\twrite(114,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (628, '\twrite(115,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (645, '\twrite(116,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (660, '\twrite(117,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (676, '\twrite(118,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (691, '\twrite(119,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (707, '\twrite(120,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (723, '\twrite(121,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (738, '\twrite(122,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (753, '\twrite(123,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (769, '\twrite(124,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (784, '\twrite(125,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (801, '\twrite(126,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (816, '\twrite(127,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)'), (832, '\twrite(128,*) px-py/2.d0, py*dsqrt(3.d0)/2.d0,gapfunction(kx,ky)')]

Python

python
grep('mag0') [(32, '\tcomplex(8) mag0(2,2)'), (33, '\treal(8) mag0_real(2,2), mag0_imag(2,2)'), (201, ' mag0(1,1) = chi_0(1,1) '), (202, ' mag0(1,2) = chi_0(1,4) '), (203, ' mag0(2,1) = chi_0(4,1) '), (204, ' mag0(2,2) = chi_0(4,4) '), (207, ' mag0_real = dble(mag0)'), (208, ' mag0_imag = dimag(mag0)'), (211, ' call ch(2,2, mag0_real, mag0_imag, w2, matz, zr2, zi2,')]

Python

python
grep('w0_max') [(29, '\treal(8) fv10(4), fv20(4), fm10(4,4), w0_max'), (194, 'c \tw0_max = maxval(w0)'), (214, ' w0_max = max(w2(1), w2(2))'), (226, ' write(37,*) px - py/2.d0, py * dsqrt(3.d0)/2.d0, -w0_max')]

Thought

Explaining sign change in code

The earlier line w0_max = maxval(w0) indicates that they initially used the 4x4 eigenvalues (w0). The switch to using the 2x2 eigenvalue (w2) is marked, and the negative sign before w0_max was likely added to adjust the colormap, as the real part of susceptibility can be negative in some cases, especially for fermionic bubbles.

Explaining the changes in results

The change you made — from diagonalizing the full susceptibility matrix to focusing on the 2x2 block — explains the small, bright ring at the center, which matches low-filling, non-interacting susceptibility (likely with a doping value of µ=-1.84). The hexagonal coordinate map and adjusted color scale a) match the model's normalization. To replicate "Fig. 2," ensure n=0.1 for appropriate doping.

Troubleshooting steps

Here's what to check:

  1. Make sure you're reading 'sus0.dat', not 'sus.dat', in your plotting script (since you labeled it 'Non-interacting').
  2. Confirm you changed from 4x4 eigenvalues to 2x2; this explains the differences you're seeing.
  3. If you used the sign flip, make sure to remove the minus when plotting.
  4. The hexagonal boundary is expected and consistent with your setup.

Thought for 2m 8s

Answer

看起来这是代码改动带来的“口径变化”,不是画图出错。

你现在的图(中心 Γ 附近出现很小的一圈高值,半径随填充变小)正是论文 Fig.2 所描述的“低填充时、以 Γ 为中心的铁磁样自旋涨落主导、在一个小圆环上取最大”的形态。你之所以从原先的图变成现在这样,主要有两点代码层面的变化:

  1. 你不再对完整的 4×4 非相互作用易感矩阵 χ0(q)\chi_0(q) 求本征值,而是先取了它的自旋通道 2×2 子块再做特征分解。
    RPA5.for 里你把
  • (旧)对 chi_0(4×4) 求本征值并取 maxval(w0) 的步骤注释掉了,
  • (新)改成构造
    mag0=(χ0(1,1)χ0(1,4)χ0(4,1)χ0(4,4))\texttt{mag0}=\begin{pmatrix}\chi_0(1,1)&\chi_0(1,4)\\ \chi_0(4,1)&\chi_0(4,4)\end{pmatrix}
    然后对这个 2×2 矩阵求本征值、取最大值 w0_max 再画图。
    这等价于投到“自旋(intra-sublattice)通道”,因此图形会从之前“混合了电荷/自旋信息的 4×4 结果”变成“在 q≈0 处强峰的小圆环”,这与论文结论一致(低填充时半径随填充缩小)。
  1. 你在写文件时对结果取了负号:
    sus0.datwrite(..., -w0_max) 输出的。
    如果你的画图脚本按“λmax(χs(0))\lambda_{\max}(\chi^{(0)}_s)”当作正值去画,这个负号会让色标范围和明暗反过来(但形状不变)。想与论文配色直观一致,可去掉这个负号,或在画图时再乘以 -1。

另外两点小提示(不影响形状,但会影响你看到的“圈的大小/亮度”):

  • 圈的半径随填充(化学势 μ)改变而变:填充越低,圈越小;你代码里当前设置 u=0(非相互作用)和某个 μ 值,对应的就是论文里“低填充”的情况。
  • 你把 (qx,qy)(q_x,q_y) 映射到了六角晶格坐标 (qxqy/2, 3qy/2)(q_x - q_y/2,\ \sqrt{3}q_y/2),所以图边界是个正六边形——这是对蜂窝晶格第一布里渊区的正确展示,不是异常。

想恢复到“改动前”的那种 4×4 总易感本征值的图,只需把对 mag0(2×2) 的特征分解改回对 chi_0(4×4) 的特征分解(并去掉输出时的负号);若只想看单个分量(例如 χ11(0)\chi^{(0)}_{11}),则直接把 -dreal(chi_0(1,1))(注意号)写出来画即可。

总之:你现在的结果其实更“物理”——它专门展示了自旋通道的最大本征值,因此在 Γ 附近出现小圆环峰,这是对的。如果你需要,我可以把 4×4 版本与 2×2 自旋通道版本并排画出来,方便直观比较差异。

Question

图片.png图片.png
截屏2025-10-11 09.47.19.png截屏2025-10-11 09.47.19.png
RPA5.for
图片.png图片.png
图片.png图片.png
图片.png图片.png
图片.png图片.png

帮我仔细检查我的.for文件,以及截图中的matlab文件,看一下为什么我画的图和文献里的fig2不一样,给出原因以及详细的解决方案

Python

python
# Let's open the provided Fortran file path = "/mnt/data/RPA5.for" with open(path, 'r', encoding='utf-8', errors='ignore') as f: content = f.read() content[:2000] ' module para_meter\n\timplicit none\n\tinteger l,n,nn,m\n\treal(8) pi,u1,u(4,4),mu,e,t1,t2,beta,eps\n\tparameter(l=100,n=l*l,nn=n*2,m=240,e=0.001)\n\treal(8) ek(l,l,2),nf(l,l,2)\n\tcomplex(8) unit(l,l,2,2),ii\n\tparameter(ii=(0.d0,1.d0),pi=3.1415926535897932384626d0,u1=0.1d0)\n\tparameter (t1=1.d0,t2=-0.2d0,beta=3.d3,eps=1.d-8)\n\tend module\n\n\tprogram main\n\tuse para_meter\n\timplicit none\n\tinteger i,j,k,iu,iv,ia,ix,iy,jx,jy,matz,ierr,ik,iq\n integer ipvt(4),job,info,row,column,mode,count,countk\n\treal(8) w(2),sgn,phi(m),v(m,m),gap(m,m),gapsymmetry(m),wg(m)\n\treal(8) zr(2,2),zi(2,2),fv1(2),fv2(2),fm1(2,2),hr(2,2),hi(2,2)\n\treal(8) px,py,sigmad(2,2),is(2,2),ran,gapfunction(l,l)\n\treal(8) wm(2),zrm(2,2),zim(2,2),fv1mag(2),fv2mag(2),fm1mag(2,2)\n\tcomplex(8) det(2),work(4),gamma(2,2,2,2,l,l,2),hk(2,2)\n\tcomplex(8) chi(2,2,2,2,l,l),chi_0(4,4),chi_c(4,4),chi_s(4,4)\n\tcomplex(8) chi_u(4,4),chi_uc(4,4),chi_us(4,4),mag(2,2),zm(2,2)\n\tinteger l1,l2,l12,l3,l4,l34,p,q,s,r,pq,sr,pr,qs,ps,qr,a,b\n\tinteger qx,qy,qx_,qy_,kx,ky,ikx(m),iky(m),ika(m),qx1,qy1\n\tlogical logic1,logic2,logic3,logic4\n\t\n\treal(8) chi0_real(4,4), chi0_imag(4,4), w0(4), zr0(4,4), zi0(4,4)\n\treal(8) fv10(4), fv20(4), fm10(4,4), w0_max\n\tinteger ierr0\n\n\tcomplex(8) mag0(2,2)\n\treal(8) mag0_real(2,2), mag0_imag(2,2)\n\treal(8) w2(2), zr2(2,2), zi2(2,2), fv12(2), fv22(2), fm12(2,2)\n\n\topen(1,file="hopping.dat")\n\topen(2,file="check.dat")\n\topen(3,file="k_point.dat")\n\topen(6,file="eigen_value.dat")\n\topen(4,file="gap_1.dat")\n\topen(5,file="gap_2.dat")\n\topen(13,file="gap_3.dat")\n\topen(14,file="gap_4.dat")\n\topen(15,file="gap_5.dat")\n\topen(16,file="gap_6.dat")\n\topen(17,file="gap_7.dat")\n\topen(18,file="gap_8.dat")\n\topen(19,file="gap_9.dat")\n\topen(20,file="gap_10.dat")\n\topen(111,file="gap_11.dat")\n\topen(112,file="gap_12.dat")\n\topen(113,file="gap_13.dat")\n\topen(114,file="gap_14.dat")\n\topen(115,file="gap_15.dat")\n\topen(116,file="gap_16.dat")\n\topen(117,file="gap_17.dat")\n\topen(118,file="gap_18.dat")\n\topen(119,file="gap_19.dat")\n\topen(120,file="gap_20.'

Python

python
len(content) 51517

Python

python
print(content[:4000])

Python

python
# Let's search for output writing and eigen values for keyword in ["sus0", "write", "w0", "mag0", "chi0", "eigen", "xh", "lambda"]: idx = content.lower().find(keyword) print(keyword, idx)

Python

python
print(content[900:1900])

Python

python
print(content[1800:3500])

Python

python
# continue from there print(content[3500:7000])

Python

python
print(content[7000:11000])

Python

python
# search for w0_max writing import re for m in re.finditer(r'w0_max', content): i = m.start() print(i) print(content[i-300:i+300])

Python

python
for keyword in ["rg", "cgeev", "rg", "hqr2", "balanc", "elmhes", "eltran", "hqr", "balbak", "eig", "qr", "cg", "rg"]: idx = content.lower().find(keyword) if idx!=-1: print(keyword, idx)

Python

python
print(content[1600:2600])

Python

python
print(content[2600:3800])

Python

python
# Continue print(content[3800:5200])

Python

python
print(content[5200:8200])

Python

python
# search for chi_0 and mag0 definitions print(content[1000:1600])

Python

python
# search further down for chi_0, mag0 assignments for key in ["chi_0", "mag0", "chi_s", "chi_uc", "chi_us"]: positions = [m.start() for m in re.finditer(key, content)] print(key, positions[:10])

Python

python
print(content[4600:5000])

Python

python
for m in re.finditer(r'nf\(', content): print(m.start(), content[m.start()-80:m.start()+200][:200])

Python

python
for m in re.finditer(r'write$\*,\*$"doping=', content): i = m.start() print(i, content[i:i+80])

Python

python
start = content.find("do qy=l/2,l") print(start) print(content[start:start+4000])

Python

python
pos = content.find("write(37") print(pos) print(content[pos-200:pos+400])

Python

python
# search upward for 'do qx' prev = content.rfind("do qx", 5000, 5400) print(prev) print(content[prev-100:prev+200])

Python

python
# search for 'do qy' earlier prev = content.rfind("do qy", 5000, 5400) print(prev) print(content[prev-100:prev+200])

Thought

Reviewing code issues

The code's loop structure is complex, but it likely resides within the do qx=1,l; do qy=1,l loops for later calculations. They previously filled half of the required elements due to symmetry. The write command seems to appear after deriving values, perhaps looping again for scanning.

The plan:

  • Summarize issues found in RPA5.for.
    1. Fix chi0 sign (wrong sign) with exact Fortran changes, such as adjusting sign correctly before writing.
    1. Address using 2×2 vs. 4×4 eigenvalues for exact replication of Fig.

Summarizing points and code fixes

  • Compute the largest eigenvalue of the 4×4 chi_0 matrix, breaking it into real and imaginary parts. Use the provided code snippet to achieve this.
  • Verify the coordinate mapping to the hexagonal BZ—adjusting qx1 and qy1 correctly.
  • For MATLAB: after fixing the sign, update the caxis and consider using a diverging colormap or 'parula'. Remove outlier clipping steps and use griddata or scatteredInterpolant for interpolation. Lastly, check the R=4π/3 setting.

Clarifying coordinate system and normalization

It seems there’s a bit of confusion about the hex boundary and radius settings. They’ve set R=1, but the plotted boundary uses R=1 as well, while the px and py mapping suggests the BZ radius should be 4π/34\pi/3. They’ve normalized px to radian units, and the overall hex boundary appears to match properly at Γ→M with that factor.

Addressing the BZ mapping and scaling

If they set R=1 but used px, py in radians, there’s a risk of incorrectly masking data beyond radius 1. However, they may have normalized qx_hex and qy_hex earlier, and the MATLAB display suggests they set ranges based on linspace with R=1. The diagnostic output further shows an unexpected range for qx_hex.

Clarifying the scaling and hex mapping

The console shows that qx and qy range from approximately -4.65 to 4.68 radians, but in the plot, the axes are scaled from -1 to 1, indicating some normalization. While the data extends beyond the unit radius, they are zooming into the central region near Γ. To display the full BZ, R should be adjusted to match the correct hex radius. Alternatively, qx and qy can be scaled by 4π/3 for normalized units.

Thought for 3m 24s

Answer

好的,我把你上传的 RPA5.for 和你截图里的 MATLAB 脚本逐行看了一遍。你现在的图和文献 Fig.2 不一致,核心有四个原因(前两个是决定性的):


结论先说

  1. Lindhard 泡泡少了整体负号
    RPA5.for 里构造 χ(0)\chi^{(0)} 的地方使用了
χ(0)kf(Ek)f(Ek+q)EkEk+q+i0+\chi^{(0)}\sim \sum_k \frac{f(E_k)-f(E_{k+q})}{E_k-E_{k+q}+i0^+}

但标准定义前面有一个 负号χ(0)(q,0)=kf(Ek)f(Ek+q)EkEk+q\chi^{(0)}(q,0)=-\sum_k\frac{f(E_k)-f(E_{k+q})}{E_k-E_{k+q}}
你现在没有这个负号,导致非相互作用自旋易感性整体变负,所以 MATLAB 图的色条全是负值(见你的 colorbar:-0.022 到 -0.001),和论文正值配色相反。

  1. 你输出的是 2×2 “自旋通道子块”的本征值,而 Fig.2 是 4×4 χ(0)\chi^{(0)} 的最大本征值
    你目前把 4×4 的 χ(0)\chi^{(0)} 取成
    mag0 = [[chi_0(1,1), chi_0(1,4)]; [chi_0(4,1), chi_0(4,4)]]
    (一个 2×2 子块)再做特征分解写进 sus0.dat。Fig.2 的说明是“noninteracting susceptibility matrix 的最大本征值”,这里指的是 4×4 χ(0)\chi^{(0)} 的最大本征值。两者形状相似(Γ 附近小圆环),但数值和配色刻度会不一样。

  2. MATLAB 只画了中心 ±1 的小窗口
    R=1,而你的数据实际范围(你命令行里打印出来了)是
    q_x ∈ [-4.65, 4.68], q_y ∈ [-2.67, 2.72](单位弧度)。
    你用 xg,yg = linspace(-R,R,N) 把网格限制在 [-1,1],因此只看到了 Γ 附近的一小块(虽然 Fig.2 重点也在中心,但想复现“整个第一布里渊区”的视觉,需要把 R 设成 BZ 的半径或把 q 归一化)。

  3. 填充(化学势 μ)要对上 n=0.1
    论文 Fig.2 用的是 filling n=0.1n=0.1。你现在 mu=-1.84d0,实际电子数(你代码里有 write(*,*) "doping=", ...)要核对是否就是 0.1。μ 不对时,那个“亮环”的半径会和论文不同。


具体定位(我在你的 RPA5.for 里看到的)

  • 构造 χ(0)\chi^{(0)} 的循环(这里应该有 整体负号):
    fortran
    chi(l1,l2,l3,l4,qx,qy) = chi(l1,l2,l3,l4,qx,qy)

& + unit(kx,ky,l4,a) * dconjg(unit(kx,ky,l1,a)) & * unit(mode(kx+qx,l),mode(ky+qy,l),l2,b) & * dconjg(unit(mode(kx+qx,l),mode(ky+qy,l),l3,b)) & * (nf(kx,ky,a)-nf(mode(kx+qx,l),mode(ky+qy,l),b)) & / (ek(kx,ky,a)-ek(mode(kx+qx,l),mode(ky+qy,l),b) + ii*eps) / n

text
这里应改成在等号右侧前面加一个负号(见下一节补丁)。 - 你输出 `sus0.dat` 的地方是写的 `w0_max`,没有人为再取负,所以数据本身就是负的,来源就是上面的符号。 - 你现在用的是自旋通道 2×2 子块: ```fortran mag0(1,1)=chi_0(1,1) mag0(1,2)=chi_0(1,4) mag0(2,1)=chi_0(4,1) mag0(2,2)=chi_0(4,4) ! 对 mag0 做特征分解 -> w2(:) -> w0_max = max(w2) write(37,*) qx_hex, qy_hex, w0_max

如果要 一模一样复现 Fig.2,应对 4×4 的 chi_0 做特征分解并写最大本征值。


可直接粘贴的修复补丁(Fortran)

目标:① 把 χ(0)\chi^{(0)} 的符号修正;② 输出 4×4 的最大本征值
(注:只为复现 Fig.2 的“非相互作用”图;后续做 RPA 时请保持同一套符号约定)

  1. 给 Lindhard 泡泡加上负号(把 + 改为 -):
fortran
! 原来 chi(...) = chi(...) & + unit(...) * dconjg(unit(...)) * unit(...) * dconjg(unit(...)) & * (nf(...) - nf'(...)) / (ek(...) - ek'(...) + ii*eps) / n ! 修改后(注意就是把第一行的 + 换成 -) chi(...) = chi(...) & - unit(...) * dconjg(unit(...)) * unit(...) * dconjg(unit(...)) & * (nf(...) - nf'(...)) / (ek(...) - ek'(...) + ii*eps) / n
  1. 用 4×4 的 chi_0 求最大本征值并写出(替换你现在的 2×2 块):
fortran
! ---- 在写 sus0.dat 之前,加入:对 4x4 chi_0 做特征分解 ---- chi0_real = dble(chi_0) chi0_imag = dimag(chi_0) call ch(4,4, chi0_real, chi0_imag, w0, matz, zr0, zi0, fv10, fv20, fm10, ierr0) w0_max = max( max(w0(1), w0(2)), max(w0(3), w0(4)) ) ! 坐标换算保持不变 px = qx1 * 2.d0 * pi / l py = qy1 * 2.d0 * pi / l ! 非相互作用应该是正的,不要再取负号 write(37,*) px - py/2.d0, py*dsqrt(3.d0)/2.d0, w0_max

如果你后面还有 RPA 的 chi_uc = - chi_uc 之类的步骤,那是相互作用通道里的约定,不影响这个“非相互作用”输出;但一旦你把 χ(0)\chi^{(0)} 的符号修正了,整套 RPA 公式要统一同一套记号(建议等复现 Fig.2 后再核对 RPA 的号)。

  1. 确保填充 n=0.1
    你代码里有
fortran
write(*,*) "doping=", count*2.d0/nn

用一个二分或牛顿法把 mu 调到 doping ≈ 0.1。最简单做法:在 mu 外套一层循环,每次根据 doping-0.1 调整 mu,直到 |误差| < 1e-4。这样圆环半径才和 Fig.2 一致。


MATLAB 脚本需要的小改动

  1. 先把数值变成正值(用上面 Fortran 修正后就不必在 MATLAB 里再乘 -1)。如果你暂时不想改 Fortran,也可以临时在读完数据后加一行:
matlab
val = -val; % 临时翻转符号,仅用于画图
  1. 坐标归一化到“hex 单位”再取 R=1(推荐):
    Fig.2 画的是整个第一布里渊区并且把 K 点半径归一化到 1。对蜂窝晶格,ΓK=4π/3|\Gamma \to K| = 4\pi/3。因此:
matlab
RK = 4*pi/3; % Γ->K 的半径 qx = qx / RK; qy = qy / RK; R = 1; % 现在 R=1 就是第一 BZ 边界

然后你现有的六边形 mask / 边界绘制函数就完全对齐 Fig.2 了,坐标轴 -1~1 也有物理意义。

  1. 色轴正向、去掉异常值剪裁
    修正符号后,设置:
matlab
valid_data = Vg(~isnan(Vg)); caxis([0, 1.05*max(valid_data)]); colormap(parula); % 视觉更接近论文配色(不强制)

你脚本里“>10×median 的异常值剪裁”可能会把亮环抹掉,建议先注释掉这段。


验收要点(你可以照这个 checklist 自测)

  • 运行 Fortran:终端打印的 doping 接近 0.1
  • 打开 sus0.dat:第三列(\lambda_\max) 为正,数量级 ~10^-2 到 10^-1(与你参数相关,不必和论文一模一样)。
  • MATLAB 画图:
    • 颜色条从 0 开始到正的最大值;
    • 整个 第一布里渊区(正六边形边界)可见;
    • Γ 点周围有一条小圆环的高值带,半径随填充变小(如果你改 mu 往低填充走,亮环会往 Γ 收缩),这与 Fig.2 一致。

如果你只想“快速得到像 Fig.2 的图”(最小改动)

  • 临时法(不改物理定义)
    只在写文件前 w0_max = -w0_max,并在 MATLAB 里把 R 设成 4*pi/3 的归一化版本(或者先把 qx,qy 除以 4*pi/3 再令 R=1)。这会马上得到“正值 + 全 BZ + 小圆环”的图。但长期建议按上面“正式修复”把 χ(0)\chi^{(0)} 的负号放在正确的位置,并用 4×4 本征值来复现 Fig.2。

需要的话,我可以把两种版本(4×4 与 2×2 子块)的图在同一配色和坐标下并排画出来,帮你确认差别。

Question

帮我生成4*4版本相应要改的代码

Thought

Generating code changes

The user wants code changes for the 4x4 version. They need modifications to accumulate the negative sign in chi0 and diagonalize a 4x4 complex matrix. I'll guide them by providing minimal diffs with anchors. I'll suggest using LAPACK's zheev for eigenvalue extraction but note that the user's file might still favor EISPACK's ch routine.

Crafting code changes

The user’s code uses ch(4,4, chi0_real, chi0_imag, w0, ...), hinting at an EISPACK-like routine for eigenvalues of complex Hermitian matrices. I’ll offer two approaches: one using LAPACK's ZHEEV and a second using their existing ch. I’ll include code for 4x4 block creation, coordinate mapping, and resetting variables. Both options will cover the needed matrix shapes and ensure no negative signs in the output.

Proposing code changes

The user is working with a 4x4 susceptibility matrix organized in sublattice form (A/B). We can create the complex matrix using real*8 arrays chi0r and chi0i and then call the existing ch subroutine for eigenvalue computation. I'll provide code to handle both the sign fix in chi_0 and matrix diagonalization while also computing the needed qx_hex, qy_hex coordinates.

Providing code change snippets

The user wants a patch to modify the sign in a specific line calculating chi(l1,l2,l3,l4,qx,qy) from + to -. I'll also keep the focus on 4x4 modifications, considering coordinate normalization and ensuring that the 4x4 matrix is Hermitian. For consistency, I'll maintain the original px and py mapping.

Thought for 36s

Answer

下面给你一份可以直接粘贴RPA5.for 的修改版片段,用来:

  • ① 纠正 Lindhard 泡泡的整体负号
  • ② 把输出从你现在用的 2×2 自旋通道子块,改成 完整 4×4 χ(0)\chi^{(0)}最大本征值
  • ③ 写出坐标的六角投影(与你的 MATLAB 脚本一致),且不再取负号

说明:下面的调用使用你文件里已有的 EISPACK 例程 ch(对复 Hermitian 矩阵求特征值)。如果你用的是 LAPACK,也给了等价的 zheev 写法(可二选一)。


1) 在累加 χ(0)\chi^{(0)} 的地方加“负号”

把你原来对 chi(...) 的累加这一行(注意你文件中的变量名可能是 chi, chi_0 等,只要是“k 和 k+q 循环里更新 χ(0)\chi^{(0)}”的那一行):

fortran
! 原来的(少了一个整体负号) chi(l1,l2,l3,l4,qx,qy) = chi(l1,l2,l3,l4,qx,qy) & + unit(kx,ky,l4,a) * dconjg(unit(kx,ky,l1,a)) & * unit(mode(kx+qx,l),mode(ky+qy,l),l2,b) & * dconjg(unit(mode(kx+qx,l),mode(ky+qy,l),l3,b)) & * (nf(kx,ky,a)-nf(mode(kx+qx,l),mode(ky+qy,l),b)) & / (ek(kx,ky,a)-ek(mode(kx+qx,l),mode(ky+qy,l),b) + ii*eps) / n

改成(仅把第 2 行最前面的 + 改为 -):

fortran
! 修改后(标准 Lindhard:前面有一个负号) chi(l1,l2,l3,l4,qx,qy) = chi(l1,l2,l3,l4,qx,qy) & - unit(kx,ky,l4,a) * dconjg(unit(kx,ky,l1,a)) & * unit(mode(kx+qx,l),mode(ky+qy,l),l2,b) & * dconjg(unit(mode(kx+qx,l),mode(ky+qy,l),l3,b)) & * (nf(kx,ky,a)-nf(mode(kx+qx,l),mode(ky+qy,l),b)) & / (ek(kx,ky,a)-ek(mode(kx+qx,l),mode(ky+qy,l),b) + ii*eps) / n

2) 用 4×4χ(0)\chi^{(0)} 求最大本征值并写出

把你现在那段“构造 mag0(2×2) → 求特征值 → write(37,*) ...整块替换为下面这段。
该代码假设你当前 q 点循环里已经有 chi_0(4,4)、格点到六角坐标的 px,py,并正准备 write(37,*)

先在变量声明区加上这些声明(若已有相同名字可忽略或合并):

fortran
real*8 chi0r(4,4), chi0i(4,4), w0(4), w0_max real*8 zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4) integer matz, ierr, i, j

然后在计算/写文件处放入(EISPACK ch 版本):

fortran
C ===4x4 的 chi_0 拆成实部/虚部(Hermitian;允许有很小的数值不对称) do i=1,4 do j=1,4 chi0r(i,j) = dreal(chi_0(i,j)) chi0i(i,j) = dimag(chi_0(i,j)) end do end do C ===4x4 的本征值(不需要特征向量) matz = 0 call ch(4,4, chi0r, chi0i, w0, matz, zr, zi, fv1, fv2, fm1, ierr) if (ierr .ne. 0) then write(*,*) 'WARN: eigen-decomp failed, ierr=', ierr end if C === 取最大本征值(非相互作用应为正,切勿再取负号) w0_max = w0(1) do i=2,4 if (w0(i) .gt. w0_max) w0_max = w0(i) end do C ===(px,py) 投到六角坐标系并写出 (qx_hex, qy_hex, lambda_max) C 这里 px,py 是你之前的 2*pi/L 物理单位;若已是 hex 单位则直接用 qx_hex = px - py/2.d0 qy_hex = py*dsqrt(3.d0)/2.d0 write(37,'(3(1x,es22.14))') qx_hex, qy_hex, w0_max

如果你更喜欢 LAPACKzheev)而不是 ch,把上面这段换成下面这种(把 use lapack 换成你工程里包含方式;注意需要链接 LAPACK):

fortran
C === LAPACK:对复 Hermitian 矩阵求本征值 complex*16 chi0z(4,4), work(1) integer lwork, info do i=1,4 do j=1,4 chi0z(i,j) = chi_0(i,j) end do end do C --- workspace query lwork = -1 call zheev('N','U',4, chi0z, 4, w0, work, lwork, info) lwork = max(16, int(dble(work))) deallocate(work) allocate(work(lwork)) C --- real call call zheev('N','U',4, chi0z, 4, w0, work, lwork, info) if (info .ne. 0) write(*,*) 'WARN: zheev failed, info=', info w0_max = w0(4) ! zheev 返回升序,最大值是 w0(4) qx_hex = px - py/2.d0 qy_hex = py*dsqrt(3.d0)/2.d0 write(37,'(3(1x,es22.14))') qx_hex, qy_hex, w0_max

☑️ 记住:不要在写出时再加负号。你的 MATLAB 脚本也就无需再 val=-val


3) 两个小提示(不改也能用,但建议)

  • χ(0)\chi^{(0)} 做一次 Hermitian 对称化(可减少数值噪声):

    fortran
    do i=1,4 do j=1,4 chi0r(i,j) = 0.5d0*( dreal(chi_0(i,j)) + dreal(chi_0(j,i)) ) chi0i(i,j) = 0.5d0*( dimag(chi_0(i,j)) - dimag(chi_0(j,i)) ) end do end do

    这样 ch/zheev 都更稳定。

  • 确保填充 n=0.1n=0.1:如果你要和论文 Fig.2 半径一致,用一个简单的外层循环调 mu 直到 abs(doping-0.1d0) < 1d-4


最后检查(快速自测)

  1. 重新跑 RPA5.for:终端打印的 doping 接近 0.1;
  2. 打开 sus0.dat:第三列全是正数
  3. 用你现有 MATLAB 脚本画:Γ 点出现小圆环高值带,色条为正、六角边界内图形与 Fig.2 一致。

需要我把你现在的 2×2 版本和新的 4×4 版本在同一坐标/色轴下并排画一个对比图的话,告诉我你想用的 μ(或 n),我这边直接给出对比绘图脚本即可。

Question

RPA6.for

编译这个代码出现这个问题,原因是什么,怎么处理?
RPA.for(34): error #5149: Illegal character in statement label field [r]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----^
RPA.for(35): error #5149: Illegal character in statement label field [i]
integer matz, ierr, i, j
----^
RPA.for(34): error #5082: Syntax error, found IDENTIFIER 'ZR' when expecting one of: :: , * <END-OF-STATEMENT> ; [ = / =>
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----------^
RPA.for(35): error #5082: Syntax error, found IDENTIFIER 'TEGERMATZ' when expecting one of: :: , * <END-OF-STATEMENT> ; [ = / =>
integer matz, ierr, i, j
------^
RPA.for(33): error #6417: The dimensions of this array have been defined more than once. [W0]
real(8) chi0r(4,4), chi0i(4,4), w0(4), w0_maxal
----------------------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [ZR]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [ZI]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
-------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FV1]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FV2]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
------------------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FM1]
re(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
--------------------------------------------^
RPA.for(35): error #6418: This name has already been assigned a data type. [IERR]
integer matz, ierr, i, j
------------------^
RPA.for(35): error #6418: This name has already been assigned a data type. [I]
integer matz, ierr, i, j
------------------------^
RPA.for(35): error #6418: This name has already been assigned a data type. [J]
integer matz, ierr, i, j
---------------------------^
compilation aborted for RPA.for (code 1)

Thought

Diagnosing Fortran compile error

The compile errors likely stem from the fixed-form Fortran format. Fixed-form expects specific column placements: columns 1-5 for labels, column 6 for continuation, and columns 7-72 for code. If "real(8) ..." starts in column 1, the "r" gets read as part of the label. A simple fix: indent the code starting from column 7 or switch to free-form compiling.

Diagnosing continuation issues in fixed-form Fortran

The error suggests improper line continuation in fixed-form Fortran. The "re(8)" error indicates that "real(8)" might have been truncated due to line continuation issues. The "w0_maxal" error may occur if "w0_max" was combined with "al" from the next line, possibly due to an incorrect use of column 6. Fortran relies on column 6 for continuation; leaving it empty causes this issue.

Analyzing fixed-form line continuation

It looks like the error originates from improper line continuation. If there's a non-blank character (like "r" from "real") in column 6, the compiler treats it as a continuation from the previous line. But the error about 'r' in columns 1-5 means it's being incorrectly placed there. Columns 1-5 should only have digits, and column 6 is for continuation.

Fixing fixed-form indentation

The issue seems to arise from 'r' being in column 5, which causes the illegal character error in the label field. In fixed-form Fortran, columns 1-5 should only contain digits or blanks, and column 6 is for continuation. The solution: indent declaration lines starting at column 7, with at least 6 spaces. Be sure column 6 stays blank for a starting line!

Clarifying Fortran issues

The issue arises from fixed-form Fortran, where any character in column 6 marks line continuation. The mistake occurred because 'r' in column 6 triggered continuation, merging lines and resulting in "w0_maxal." The solution: either switch to free-form (renaming the file with .f90 and using -free flag) or fix the line continuations for the fixed-form by starting new statements from column 7.

Thought for 55s

Answer

你这些错误都是固定格式 Fortran(.for)排版+重复声明导致的,并不是算法问题。

发生了什么

  • .for 默认是 fixed-form。在 fixed-form 里:

    • 第 1–5 列是语句标签栏,只能是空格或数字;
    • 第 6 列是续行标志(非空即把本行当作上一行的续行);
    • 第 7 列以后才是代码。
  • 你把 real(8) 直接从第 1 或第 5 列开始写,编译器把字母 r/i 认为出现在“标签栏/续行栏”,于是报:

    Illegal character in statement label field [r],[i]
    

    并且由于第 6 列非空,本行被当作上一行的续行,把

    text
    ..., w0_max real(8) zr(4,4), ...

    拼成了 w0_maxalrealal 接在了前一行末尾),于是后面一串语法/重复维度错误全被连锁触发。

  • 同时你又重复声明了已经在本程序里出现过的名字(例如 w0ierrij),因此有:

    text
    The dimensions of this array have been defined more than once [W0] This name has already been assigned a data type [IERR/I/J]

两种修法(二选一)

方案 A:继续用 fixed-form(.for)

  1. 把新加的声明行起始至少缩进 6 个空格(从第 7 列开始),并且不要在第 6 列放任何字符(否则会被当续行)。
  2. 不要重复声明程序里已经声明过的变量(如 w0ierrij)。若不确定,给新变量换个不冲突的名字。

示例(可直接替换你的那两行声明)

fortran
real*8 chi0r(4,4), chi0i(4,4), eval0(4), eval0_max real*8 zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4) integer matz C (如程序中已有 IERR/I/J 的声明,这里不要再声明它们)

后续求特征值的调用相应改名(把原来的 w0 换成 eval0w0_max 换成 eval0_max):

fortran
matz = 0 call ch(4,4, chi0r, chi0i, eval0, matz, zr, zi, fv1, fv2, fm1, ierr) eval0_max = eval0(1) do ii = 2,4 if (eval0(ii) .gt. eval0_max) eval0_max = eval0(ii) end do write(37,'(3(1x,es22.14))') qx_hex, qy_hex, eval0_max

注意:行首必须从第 7 列开始,第 6 列保持空格,这样就不会再被当续行。

方案 B:改用 free-form(推荐)

把文件后缀改成 .f90 或用编译选项让编译器按 free-form 解析:

  • gfortran -ffree-form RPA.f90
  • ifort -free RPA.f90

然后把声明写成普通格式(不需要固定列对齐,也可用 & 续行):

fortran
real(8) :: chi0r(4,4), chi0i(4,4), eval0(4), eval0_max real(8) :: zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4) integer :: matz ! integer :: ierr, i, j ! 若前面已有声明则不要重复

顺手避免的两个坑

  • 不要再次声明已存在的数组/变量:如果程序里已声明了 w0(4),就改名用 eval0(4) 或把原 w0 直接复用,不要再 real*8 w0(4) 一次。
  • 续行(仅 fixed-form):如果一行太长需要续行,把下一行第 6 列放任意非空字符(常用 &),并从第 7 列继续写;否则保持第 6 列为空表示新的一行

一段“固定格式”安全示例(可直接抄用)

fortran
C --- declarations (fixed-form; start at col 7) real*8 chi0r(4,4), chi0i(4,4), eval0(4), eval0_max real*8 zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4) integer matz C --- build chi0r/chi0i ... do i=1,4 do j=1,4 chi0r(i,j) = dreal(chi_0(i,j)) chi0i(i,j) = dimag(chi_0(i,j)) end do end do C --- eigenvalues (EISPACK ch) matz = 0 call ch(4,4, chi0r, chi0i, eval0, matz, zr, zi, fv1, fv2, fm1, ierr) eval0_max = eval0(1) do ii=2,4 if (eval0(ii) .gt. eval0_max) eval0_max = eval0(ii) end do qx_hex = px - py/2.d0 qy_hex = py*dsqrt(3.d0)/2.d0 write(37,'(3(1x,es22.14))') qx_hex, qy_hex, eval0_max

按以上修改后,再编译即可消除这些错误。如果还有报“重复维度/已声明”的错误,把报错的那个名字在整个同一程序/子程序里搜一下,删掉重复的 real*8/integer 声明或换个新名字即可。

Question

RPA7.for

我的代码哪里有问题?为什么无法编译,请给出修改的代码:RPA.for(33): error #6417: The dimensions of this array have been defined more than once. [W0]
real(8) chi0r(4,4), chi0i(4,4), w0(4), w0_max
------------------------------------------------^
RPA.for(33): error #6418: This name has already been assigned a data type. [W0_MAX]
real(8) chi0r(4,4), chi0i(4,4), w0(4), w0_max
-------------------------------------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [ZR]
real(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [ZI]
real(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
-------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FV1]
real(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
----------------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FV2]
real(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
------------------------------------------^
RPA.for(34): error #6417: The dimensions of this array have been defined more than once. [FM1]
real(8) zr(4,4), zi(4,4), fv1(4), fv2(4), fm1(4)
--------------------------------------------------^
RPA.for(35): error #6418: This name has already been assigned a data type. [MATZ]
integer matz
----------------^
compilation aborted for RPA.for (code 1)

Thought

Debugging Fortran errors

The user's provided error messages indicate that some variables are being declared multiple times within the same scope (like w0, w0_max, zr, etc.). The solution is to remove duplicate declarations or rename variables to avoid repetition. Also, ensure proper fixed-form formatting. If needed, restructure with subroutines or adjusted names for eigen decomposition.

Correcting code and avoiding variable duplication

To avoid duplication, I suggest using new variable names like ev0(4), evmax0, and zrr4(4,4) instead of w0 and others already declared in the program. If earlier variables like w0 are needed, ensure their reuse. Additionally, place all declarations at the start of the subroutine as Fortran 77 requires.

Fixing variable duplication

The errors suggest variable duplication, not issues with placement after executable statements. To resolve this, I'll propose removing the earlier duplicate declarations and replacing them with uniquely named variables like chi0r4, chi0i4, eval4(4), eval4_max, etc. This will ensure no conflicts with previously defined variables.

Finalizing code fix and patch

All variable names should be unique. Replace later references, such as “call ch” and “evmax.” Also, ensure that column positions start at column 7 for fixed form, or compile with -free for better flexibility. A patch should also include a fix for Lindhard's negative sign issue.

Thought for 19s

Answer

这些报错都是重复声明导致的(同一个作用域里把同名变量/数组又声明了一次)。
报错里点名的有:w0w0_maxzrzifv1fv2fm1matz——说明这些名字在你的程序/子程序里之前已经声明过(可能是你先做过 2×2 本征值时就声明了),你现在又声明了一遍,所以编译器直接报:

  • The dimensions of this array have been defined more than once.
  • This name has already been assigned a data type.

另外,如果你的文件是 .forfixed-form),记得从第 7 列开始写代码;第 6 列不要放字符,否则会被当成上一行的续行,容易连带出更多语法错。


修改方法(直接可用的补丁,避免与旧变量重名)

目标:计算 4×4χ(0)\chi^{(0)} 最大本征值并写出;全部使用全新变量名,不和你现有的 w0zr 等冲突。以下为 fixed-form 写法(行首 6 个空格)。

1) 变量声明(放在声明区,且第 7 列开始)

fortran
real*8 chi0r4(4,4), chi0i4(4,4), eval4(4), eval4_max real*8 zrr4(4,4), zir4(4,4), wv1(4), wv2(4), wm1(4) integer imatz

若你的程序里已经有 ierrij 的声明,就不要在这里再声明它们;下面代码直接复用你原来的 i,j,ierr

2) 构造实/虚部并对称化(可放在每个 q 点的循环里)

fortran
C ---4x4 chi_0 分解为实部/虚部,并做一次 Hermitian 对称化(更稳) do i = 1,4 do j = 1,4 chi0r4(i,j) = 0.5d0 * ( dreal(chi_0(i,j)) + dreal(chi_0(j,i)) ) chi0i4(i,j) = 0.5d0 * ( dimag(chi_0(i,j)) - dimag(chi_0(j,i)) ) end do end do

3) 求本征值(EISPACK ch 例程)

fortran
imatz = 0 call ch(4,4, chi0r4, chi0i4, eval4, imatz, zrr4, zir4, wv1, wv2, wm1, ierr) eval4_max = eval4(1) do i = 2,4 if (eval4(i) .gt. eval4_max) eval4_max = eval4(i) end do

4) 写出到 sus0.dat(保持你的六角坐标映射,不要再取负号)

fortran
C --- 六角坐标(与你原来一致) qx_hex = px - py/2.d0 qy_hex = py * dsqrt(3.d0) / 2.d0 write(37,'(3(1x,es22.14))') qx_hex, qy_hex, eval4_max

上面代码完全避免使用 w0w0_maxzrzifv1fv2fm1matz 这些已存在的名字,因此不会再触发重复声明错误。


如果你更喜欢 free-form(推荐)

把文件改名为 .f90 或用编译选项(gfortran: -ffree-form,ifort: -free),然后用现代声明(不受列位限制):

fortran
real(8) :: chi0r4(4,4), chi0i4(4,4), eval4(4), eval4_max real(8) :: zrr4(4,4), zir4(4,4), wv1(4), wv2(4), wm1(4) integer :: imatz

其余计算部分与上文相同。


额外提醒(避免后续再踩坑)

  1. 不要重复声明:同一程序/子程序里,一个名字只能声明一次。想再做一套运算时,换新名字(如 eval4 而不是 w0)。
  2. fixed-form 缩进:声明/代码从第 7 列开始;第 6 列非空表示续行。
  3. 物理符号:前面我们讨论过 Lindhard 泡泡需要整体负号。别忘了在累加 χ(0)\chi^{(0)} 的地方把 + 改为 -(只改那一行的号即可),这样写出的本征值应为正值,与你 MATLAB 的配色一致。

照此改完再编译,以上这些“重复定义/已分配类型”的错误就会消失了。若仍有报错,把报错名字在文件里全局搜一下,确认只保留一次声明即可。

Share this Q&A