Loops Fortran:如何使用多个文件重复执行作业

Loops Fortran:如何使用多个文件重复执行作业,loops,makefile,fortran,repeat,Loops,Makefile,Fortran,Repeat,项目描述: ! calculate distances from the city center to each McDonald ! Try this for all the cities program mcdonalds implicit none interface function distkm(deglat1,deglon1,deglat2,deglon2) real :: distkm real, intent(in

项目描述:

! calculate distances from the city center to each McDonald 
! Try this for all the cities
program mcdonalds
    implicit none
    interface
        function distkm(deglat1,deglon1,deglat2,deglon2)
        real :: distkm
        real, intent(in) :: deglat1,deglon1,deglat2,deglon2
        end function distkm
    end interface

    integer, parameter :: maxnr = 200
    integer :: nr, i, j, ios
    character(len=1) :: junkfornr
    character(len=25) :: fn

    real, dimension(:), allocatable :: lat, lon
    real, dimension(5) :: clat, clon
    character(len=15), dimension(5) :: filename
            character(len=6), dimension(5) :: code
    character(len=7), dimension(5) :: cityname

    ! I have a text file that contains the list of data file names, city names and the (lat/lon)s of city centers.
    ! The name of that file: datafilelistcitycenter.txt
    ! === The content of the file looks like: ===
    ! atlanta_mc.txt  11111  atlanta  33.79526   -84.326528
    ! houston_mc.txt  22222  houston  29.733215  -95.430824
    ! la_mc.txt       33333  la       34.057453  -118.413842
    ! ny_mc.txt       44444  ny       40.759347  -73.980202
    ! philly_mc.txt   55555  philly   29.733215  -95.430824

    ! Let's assume we know the number of the cities. 
    ! In this case, it is 5.

    open(10, file='datafilelistcitycenter.txt', status='old')
    rewind(10)
    do i=1,5
        read(10,*) filename(i), cityname(i), clat(i), clon(i)
    end do
    close(10)

    ! Obtain the total number of observations for each city
    do j=1,5

    open(j, file=filename(j), status='old')
    nr=0
    do i=1,maxnr
        read(j,*,iostat=ios) junkfornr
        if (ios/=0) exit
        if (i == maxnr) then
            write(*,*) "Error: Maximum number of records exceeded..."
            write(*,*) "Exiting the program..."
            stop
        endif
        nr = nr + 1
    end do

    allocate(lat(nr),lon(nr))

    rewind(j)
    do i=1,nr
        read(j,*) lat(i), lon(i)
    end do
    close(j)

    write(fn, '("RESULT_",A15)') filename(j)
    open(j,file=fn)

    do i=1,nr
        write(j,100) code(j),cityname(j),lat(i),lon(i),distkm(lat(i),lon(i),clat(j),clon(j))
        100 format(A6,A7,3F12.6)
    end do
    close(j)

    deallocate(lat,lon)

    end do

end program mcdonalds

function distkm(deglat1,deglon1,deglat2,deglon2)
    implicit none 
    real, intent(in) :: deglat1,deglon1,deglat2,deglon2
    real :: pi,dlat,dlon,lat1,lat2,a,distkm
    pi = 4*atan(1.0)
    dlat = (deglat2-deglat1)*pi/180
    dlon = (deglon2-deglon1)*pi/180
    lat1 = deglat1*pi/180
    lat2 = deglat2*pi/180
    a = (sin(dlat/2))**2 + cos(lat1)*cos(lat2)*(sin(dlon/2))**2
    distkm = 6372.8*2*atan2(sqrt(a),sqrt(1-a))
end function distkm 
我有城市中麦当劳的坐标和城市中心的坐标。它们按城市划分为文本文件。比如说,

 === atlanta_mc.txt ===    === houston_mc.txt ===    ... (for 200 cities)
[latitude]   [longitude]   [latitude] [longitude]    <-- The headers are not written in the files.   
33.5431140  -84.5766910    29.8044570 -95.3990780
34.0489350  -84.0928960    30.0051170 -95.2834550
33.7853660  -84.1018980    29.7371140 -95.5352550   
34.0903210  -84.2040180    29.7280160 -95.4188230 
34.1606520  -84.1781010    29.7851700 -95.3609770
         ....                       ....
问题:

! calculate distances from the city center to each McDonald 
! Try this for all the cities
program mcdonalds
    implicit none
    interface
        function distkm(deglat1,deglon1,deglat2,deglon2)
        real :: distkm
        real, intent(in) :: deglat1,deglon1,deglat2,deglon2
        end function distkm
    end interface

    integer, parameter :: maxnr = 200
    integer :: nr, i, j, ios
    character(len=1) :: junkfornr
    character(len=25) :: fn

    real, dimension(:), allocatable :: lat, lon
    real, dimension(5) :: clat, clon
    character(len=15), dimension(5) :: filename
            character(len=6), dimension(5) :: code
    character(len=7), dimension(5) :: cityname

    ! I have a text file that contains the list of data file names, city names and the (lat/lon)s of city centers.
    ! The name of that file: datafilelistcitycenter.txt
    ! === The content of the file looks like: ===
    ! atlanta_mc.txt  11111  atlanta  33.79526   -84.326528
    ! houston_mc.txt  22222  houston  29.733215  -95.430824
    ! la_mc.txt       33333  la       34.057453  -118.413842
    ! ny_mc.txt       44444  ny       40.759347  -73.980202
    ! philly_mc.txt   55555  philly   29.733215  -95.430824

    ! Let's assume we know the number of the cities. 
    ! In this case, it is 5.

    open(10, file='datafilelistcitycenter.txt', status='old')
    rewind(10)
    do i=1,5
        read(10,*) filename(i), cityname(i), clat(i), clon(i)
    end do
    close(10)

    ! Obtain the total number of observations for each city
    do j=1,5

    open(j, file=filename(j), status='old')
    nr=0
    do i=1,maxnr
        read(j,*,iostat=ios) junkfornr
        if (ios/=0) exit
        if (i == maxnr) then
            write(*,*) "Error: Maximum number of records exceeded..."
            write(*,*) "Exiting the program..."
            stop
        endif
        nr = nr + 1
    end do

    allocate(lat(nr),lon(nr))

    rewind(j)
    do i=1,nr
        read(j,*) lat(i), lon(i)
    end do
    close(j)

    write(fn, '("RESULT_",A15)') filename(j)
    open(j,file=fn)

    do i=1,nr
        write(j,100) code(j),cityname(j),lat(i),lon(i),distkm(lat(i),lon(i),clat(j),clon(j))
        100 format(A6,A7,3F12.6)
    end do
    close(j)

    deallocate(lat,lon)

    end do

end program mcdonalds

function distkm(deglat1,deglon1,deglat2,deglon2)
    implicit none 
    real, intent(in) :: deglat1,deglon1,deglat2,deglon2
    real :: pi,dlat,dlon,lat1,lat2,a,distkm
    pi = 4*atan(1.0)
    dlat = (deglat2-deglat1)*pi/180
    dlon = (deglon2-deglon1)*pi/180
    lat1 = deglat1*pi/180
    lat2 = deglat2*pi/180
    a = (sin(dlat/2))**2 + cos(lat1)*cos(lat2)*(sin(dlon/2))**2
    distkm = 6372.8*2*atan2(sqrt(a),sqrt(1-a))
end function distkm 
我必须为所有城市做这件事。因此,我必须更改(1)麦当劳数据文件,(2)市中心坐标;(3)每个城市相应的结果文件。我要如何编写一个程序来迭代整个200个城市的这个过程?我使用英特尔Fortran(ifort)编译它

编辑(该代码有效——2014年4月11日,星期五):

! calculate distances from the city center to each McDonald 
! Try this for all the cities
program mcdonalds
    implicit none
    interface
        function distkm(deglat1,deglon1,deglat2,deglon2)
        real :: distkm
        real, intent(in) :: deglat1,deglon1,deglat2,deglon2
        end function distkm
    end interface

    integer, parameter :: maxnr = 200
    integer :: nr, i, j, ios
    character(len=1) :: junkfornr
    character(len=25) :: fn

    real, dimension(:), allocatable :: lat, lon
    real, dimension(5) :: clat, clon
    character(len=15), dimension(5) :: filename
            character(len=6), dimension(5) :: code
    character(len=7), dimension(5) :: cityname

    ! I have a text file that contains the list of data file names, city names and the (lat/lon)s of city centers.
    ! The name of that file: datafilelistcitycenter.txt
    ! === The content of the file looks like: ===
    ! atlanta_mc.txt  11111  atlanta  33.79526   -84.326528
    ! houston_mc.txt  22222  houston  29.733215  -95.430824
    ! la_mc.txt       33333  la       34.057453  -118.413842
    ! ny_mc.txt       44444  ny       40.759347  -73.980202
    ! philly_mc.txt   55555  philly   29.733215  -95.430824

    ! Let's assume we know the number of the cities. 
    ! In this case, it is 5.

    open(10, file='datafilelistcitycenter.txt', status='old')
    rewind(10)
    do i=1,5
        read(10,*) filename(i), cityname(i), clat(i), clon(i)
    end do
    close(10)

    ! Obtain the total number of observations for each city
    do j=1,5

    open(j, file=filename(j), status='old')
    nr=0
    do i=1,maxnr
        read(j,*,iostat=ios) junkfornr
        if (ios/=0) exit
        if (i == maxnr) then
            write(*,*) "Error: Maximum number of records exceeded..."
            write(*,*) "Exiting the program..."
            stop
        endif
        nr = nr + 1
    end do

    allocate(lat(nr),lon(nr))

    rewind(j)
    do i=1,nr
        read(j,*) lat(i), lon(i)
    end do
    close(j)

    write(fn, '("RESULT_",A15)') filename(j)
    open(j,file=fn)

    do i=1,nr
        write(j,100) code(j),cityname(j),lat(i),lon(i),distkm(lat(i),lon(i),clat(j),clon(j))
        100 format(A6,A7,3F12.6)
    end do
    close(j)

    deallocate(lat,lon)

    end do

end program mcdonalds

function distkm(deglat1,deglon1,deglat2,deglon2)
    implicit none 
    real, intent(in) :: deglat1,deglon1,deglat2,deglon2
    real :: pi,dlat,dlon,lat1,lat2,a,distkm
    pi = 4*atan(1.0)
    dlat = (deglat2-deglat1)*pi/180
    dlon = (deglon2-deglon1)*pi/180
    lat1 = deglat1*pi/180
    lat2 = deglat2*pi/180
    a = (sin(dlat/2))**2 + cos(lat1)*cos(lat2)*(sin(dlon/2))**2
    distkm = 6372.8*2*atan2(sqrt(a),sqrt(1-a))
end function distkm 
不走运。我最终得到了非常奇怪的消息:严重:输出语句溢出记录,第5单元,文件内部格式化写入


编辑:我想我是对的。谢谢。

不要打开一个特定的城市文件,如atlanta_mc.tx,而是创建一个包含该城市文件名列表的文件。打开该文件,在程序中添加一个新循环,读取城市文件的名称,像现在一样打开并处理它,然后关闭该文件。新循环的下一次迭代将处理下一个城市文件等。这是假设城市位于单独的文件中。如果它们在一个大文件中,那么创建数组来保存所有城市的信息,将所有信息读入数组,然后创建一个新的循环来迭代城市


此外,如果您将函数
distkm
放入一个模块中,则无需为其设置
接口。使用模块,更简单,更不容易出错。例如:distkm

Hi MSB。我试过你的方法。但有些事情进展不顺利。你能看看我错过了什么吗?谢谢如果您指明了行号,这将有所帮助。我假设
write(fn'(“RESULT”,A))filename(j)
,因为这似乎是唯一的内部写入。要使其正常工作,
fn
需要是一个足够长的字符串,以容纳
RESULT\u a
和文件名。但是被声明为
character::fn
,它只有一个字符长——请在声明中添加长度。感谢您对“fn”长度的帮助。