Fortran:读取文件中不存在的变量

时间:2016-04-05 06:46:48

标签: file-io fortran

我需要帮助理解这个50行程序

  implicit none
  integer           maxk, maxb, maxs
  parameter         (maxk=6000, maxb=1000, maxs=5)
  integer           nk, nspin, nband, ik, is, ib
  double precision  e(maxb, maxs, maxk), k(maxk)
  double precision  ef, kmin, kmax, emin, emax
  logical           overflow

  read(5,*) ef
  read(5,*) kmin, kmax
  read(5,*) emin, emax
  read(5,*) nband, nspin, nk

  overflow = (nband.gt.maxb) .or. (nk.gt.maxk) .or. (nspin.gt.maxs)
  if (overflow) stop 'Dimensions in gnubands too small'

  write(6,"(2a)") '# GNUBANDS: Utility for SIESTA to transform ',
 .                'bands output into Gnuplot format'
  write(6,"(a)") '#'
  write(6,"(2a)") '#                                           ',
 .                '       Emilio Artacho, Feb. 1999'
  write(6,"(2a)") '# ------------------------------------------',
 .                '--------------------------------'
  write(6,"(a,f10.4)")  '# E_F               = ', ef
  write(6,"(a,2f10.4)") '# k_min, k_max      = ', kmin, kmax
  write(6,"(a,2f10.4)") '# E_min, E_max      = ', emin, emax
  write(6,"(a,3i6)")    '# Nbands, Nspin, Nk = ', nband, nspin, nk
  write(6,"(a)") '#'
  write(6,"(a)") '#        k            E'
  write(6,"(2a)") '# ------------------------------------------',
 .                '--------------------------------'

  read(5,*) (k(ik),((e(ib,is,ik),ib=1,nband), is=1,nspin), ik=1,nk)

  do is = 1, nspin
    do ib = 1, nband
       write(6,"(2f14.6)") ( k(ik), e(ib,is,ik), ik = 1, nk)
       write(6,"(/)")
    enddo
  enddo

这是一个免费格式的Fortran文件。程序的名称是gnubands并重新排列输入中的数字(用户指定)。我想知道这个程序是如何运作的。这是我不明白的。程序从文件中获取输入,它读取

ef, kmin,kmax,emin,emax,nband,nspin,nk

但是,在输入文件中找不到所有这些变量。我在vi中打开输入文件并使用/进行搜索。我没有得到任何结果。尽管如此,程序似乎正确地选择了所有值。怎么了? 另外,我不懂读取格式

read(5,*) (k(ik),((e(ib,is,ik),ib=1,nband), is=1,nspin), ik=1,nk)

我不熟悉语法,想知道它的含义或参考文献。

2 个答案:

答案 0 :(得分:1)

Some tutorial PDF of SIESTA表明gnubands.f的输入是这样的:

enter image description here

其标题部分将由gnubands.f的前四个read语句读取。使用此输入,变量设置为

ef    = -5.018...
kmin  = 0.000...
kmax  = 3.338...
emin  = -25.187...
emax  = 143.069...
nband = 18
nspin = 1
nk    = 150

将标准输入(假设单元号5)的输入文件作为

gfortran -o gnubands.x gnubands.f
gnubands.x < your_data_file.bands  

请注意,有(并且应该)没有像&#34; ef&#34;或&#34; EF&#34;或者&#34; Ef&#34; (大写无关紧要),因为数字直接读入gnubands.f中的变量。这与使用XML文件的其他情况形成对比,其中(人类可读的)标签或关键字嵌入在文件本身中(例如,Quantum ESPRESSO使用的伪势文件)。我猜你的混淆可能来自使用namelist获取输入值,看起来像

namelist /your_inp/ a, b, c
read( funit, nml = your_inp )

带有输入文件

&your_inp
a = 1.0
b = "method1"
c = 77
/

在这种情况下,变量名称(此处为a,b和c)在字面上显示在输入文件中。

答案 1 :(得分:0)

从历史上看,5(在您的read(5,*)中)是stdin,所以也是如此 (1)当您运行代码时,您正在提供值, 或者,(2)我猜你在运行SIESTA时,(gnuband是后处理器)它会创建一个文件,可能名为fort.5。检查一下。