2017-10-09 157 views
2

我想用不同的輸入參數集多次運行fortran 77程序;我已經確定輸出文件名稱會隨着我使用的不同輸入參數而變化,但我不確定如何使用不同的輸入參數集來運行程序,而不必每次都去代碼來更改參數。使用不同的輸入參數在fortran中多次運行代碼

爲了說明我的問題,下面是一個簡單的代碼。

PROGRAM CODE 
    IMPLICIT DOUBLE PRECISION (A-H, J-Z) 
    COMMON/param/radius 

    radius = 2 
    write(*,*) 'radius = ', radius 
    write(*,*) 'the area is = ', 3.14*radius*radius 

    END 

說我要運行該代碼具有不同的半徑,和而不必進入代碼和手動更改的價值,我想有不同的參數選擇一個文件,然後就能運行多次。

當然,通過創建一個不同的參數選擇和循環的數組有一個解決方案。但是,我不想這樣做,因爲我實際上有多個參數,我想爲每次運行更改。

迴應下面的評論之一,如果我有一個文件在每次運行時都有不同的輸入選擇,我如何讓程序爲每次運行的不同參數選擇抓取不同的行?

+3

那麼有些人會用他們最喜歡的腳本語言編寫一個小腳本來爲每個程序的執行提供一些輸入參數。對於任何真實答案,請提出問題。 (不,您發佈的內容不是問題。) –

+1

您可能想要查找'Get_command_argument' – agentp

+1

另一種選擇是讀取包含每次運行所需的輸入參數的數據文件。 –

回答

6

我有很多次使用「行人」式的方法。

爲避免重新編譯,一種解決方案是硬編碼參數文件的名稱並從該文件讀取數據。代碼的每次運行都必須具有自己的參數副本,以及它自己的目錄。

我給出了一個單個參數的例子,但是如果需要的話可以推廣它。它依靠bash中的驅動程序腳本。

Fortran程序:

 PROGRAM CODE 
     IMPLICIT DOUBLE PRECISION (A-H, J-Z) 
     COMMON/param/radius 

     open(11, file='parameters.txt') 
     read(11,*) radius 
     close(11) 
     write(*,*) 'radius = ', radius 
     write(*,*) 'the area is = ', 3.14*radius*radius 

     END 

bash程序:

for radius in 01 02 05 10 
do 
RUNDIR=run_${radius} 
mkdir ${RUNDIR} 
echo "${radius}" > ${RUNDIR}/parameters.txt 
(cd ${RUNDIR} ; ../code) 
done 

編譯Fortran代碼:

gfortran -std=legacy -o code code.f 

並執行運行參數如:

bash parametricrun.sh 
  1. Fortran代碼的功能:打開名爲parameters.txt的文件並讀取radius的第一個條目。

  2. 的bash腳本的作用:對於一些參數的值,創建一個新的目錄,在該目錄中創建一個名爲parameters.txt文件,然後在該目錄執行Fortran程序code

評論:

  1. 這可以使用在bash程序的第二環被擴展到幾個變量,每任一行或數每行中parameters.txt

  2. 如果您可以使用更現代的Fortran版本,請提及它。那裏有更多的選擇。

  3. 其他語言(Python,arclight建議,或其他)可用於腳本編寫。許多計算集羣使用bash來運行作業,因此可以用於參數運行(然後可以通過作業排隊系統傳遞radius的值)。

  4. 我用了11個任意的文件單元號。您的實際情況確實需要爲您的程序使用可用的單元號。

+0

這是我會用的方法,但卻懶得寫。在Windows中也可以使用,只是腳本略有不同。不需要特殊的編程語言。我真的不認爲用戶提出基本問題就能夠從一些描述中編寫Python腳本,而不需要任何代碼。 –

+0

文件方法的優點是可以歸檔輸入文件。如果只有少數幾個參數,我通常會使用它。 – agentp

+0

謝謝你的幫助。我堅持使用Fortran 77的原因是,我正在使用我的同事在Fortran 77中寫的一段代碼。我對程序員不是很瞭解,但是有沒有辦法將fortran 77代碼更改爲更新的版本? –

0

如果更改爲代碼,則需要重新編譯。

我不知道你的程序有多複雜,通常最好是以這樣一種方式編寫程序,以便從用戶界面或文件中讀取值。

檢查CHECK_COMMAND_ARGUMENTNamelists想法如何做到這一點。

但是,如果您想每次重新編譯它,可以使用預處理器來設置代碼的某些部分。

請參見本示例代碼:

 PROGRAM area 
     IMPLICIT NONE 
     PRINT *, "area of circle with radius ", RADIUS, " is ", 
    &   3.15159 * RADIUS**2 
     END PROGRAM area 

要使用預處理,你要麼必須明確地告訴你的編譯器做(gfortran -cppifort -fpp爲例),也可以擴展名更改爲資本.F(或用於現代Fortran的.F90),默認啓用預處理器。

$ gfortran -D RADIUS=2 area.F -o area 
$ ./area 
area of circle with radius   2 is 12.6063604 
$ gfortran -D RADIUS=20 area.F -o area 
$ ./area 
area of circle with radius   20 is 1260.63599 
+0

雖然我現在有第二個想法告訴人們沒有太多有關預處理程序的編程經驗......他們可以有奇怪的效果... – chw21

+5

教人們重新編譯爲每個不同的程序執行,這是一種*怪異效果* ... –

0

在案件我已經運行在其期望在一組的參數運行代碼的參數分析,我在Python中使用Jinja2的模板庫產生大量寫了一個小腳本輸入文件的數量。我選擇了一個命名約定,使我能夠輕鬆確定哪個輸入文件對應哪個輸入排列以幫助後處理結果。 Python &的具體用法Jinja2與輸入生成腳本外部的文本模板不同,因此您可以在不編輯輸入生成器的情況下對生成的文件進行調整。有很多成熟,簡單的網頁模板系統可以高效地生成輸入文本文件。

輸入參數和文件名之間的交叉引用可能與數據結構數組(如哈希或字典)中的索引一樣簡單。我嘗試使用更有意義的內容,併爲生成的輸入添加描述性註釋(假設輸入格式允許註釋...)

就我而言,我可能使用的代碼不經過一個月的QA循環就無法重新編譯,因此將參數化變體代碼編寫爲單獨的腳本比將其集成到單獨的腳本要便宜得多我的Fortran代碼。

我傾向於在Python中編寫參數分析代碼的另一個原因是因爲它比在Fortran中編寫複雜輸入處理容易得多。能夠使用numpy來生成線性,對數或其他變體模式(例如Chebyshev節點)比在Fortran中嘗試使用它容易得多。

標準免責聲明:我的操作環境和用例可能與您的操作環境和用例非常不同,所以此技術可能不合適。我只是指出,這是一個具有幾個優點的選項,具體取決於您的環境。

1

命令行參數的方法

implicit none 
    real r 
    character*30 arg 
    integer ios 
    if(command_argument_count().eq.0)then 
! default for no argument 
    r=1. 
    else 
    call get_command_argument(1,arg) 
    read(arg,*,iostat=ios)r 
    if(ios.ne.0)then 
     write(*,*)'error expected number arg got ',arg 
     stop 
    endif 
    endif 
    write(*,*)r 
    end 

注古代的編譯器,你應該使用iargcgetarg代替。純粹主義者會注意到這些是非標準的f77,然而它們通常在許多編譯器中可用。

典型的Python腳本遍歷參數列表:

import os 
for r in (1.2,6.6): os.system('fortran_program %g'%r) 
當然,你應該使用任何的腳本語言,你是舒服的

。我喜歡「高級」語言,因爲我不可避免地似乎最終要在腳本中進行計算。

相關問題