使用不同的输入参数在fortran中多次运行代码
我想用不同的输入参数集多次运行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
说我要运行该代码具有不同的半径,和而不必进入代码和手动更改的价值,我想有不同的参数选择一个文件,然后就能运行多次。
当然,通过创建一个不同的参数选择和循环的数组有一个解决方案。但是,我不想这样做,因为我实际上有多个参数,我想为每次运行更改。
回应下面的评论之一,如果我有一个文件在每次运行时都有不同的输入选择,我如何让程序为每次运行的不同参数选择抓取不同的行?
我有很多次使用“行人”式的方法。
为避免重新编译,一种解决方案是硬编码参数文件的名称并从该文件读取数据。代码的每次运行都必须具有自己的参数副本,以及它自己的目录。
我给出了一个单个参数的例子,但是如果需要的话可以推广它。它依靠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
Fortran代码的功能:打开名为
parameters.txt
的文件并读取radius的第一个条目。的bash脚本的作用:对于一些参数的值,创建一个新的目录,在该目录中创建一个名为
parameters.txt
文件,然后在该目录执行Fortran程序code
。
评论:
这可以使用在bash程序的第二环被扩展到几个变量,每任一行或数每行中
parameters.txt
。如果您可以使用更现代的Fortran版本,请提及它。那里有更多的选择。
其他语言(Python,arclight建议,或其他)可用于脚本编写。许多计算集群使用bash来运行作业,因此可以用于参数运行(然后可以通过作业排队系统传递radius的值)。
我用了11个任意的文件单元号。您的实际情况确实需要为您的程序使用可用的单元号。
这是我会用的方法,但却懒得写。在Windows中也可以使用,只是脚本略有不同。不需要特殊的编程语言。我真的不认为用户提出基本问题就能够从一些描述中编写Python脚本,而不需要任何代码。 –
文件方法的优点是可以归档输入文件。如果只有少数几个参数,我通常会使用它。 – agentp
谢谢你的帮助。我坚持使用Fortran 77的原因是,我正在使用我的同事在Fortran 77中写的一段代码。我对程序员不是很了解,但是有没有办法将fortran 77代码更改为更新的版本? –
如果更改为代码,则需要重新编译。
我不知道你的程序有多复杂,通常最好是以这样一种方式编写程序,以便从用户界面或文件中读取值。
检查CHECK_COMMAND_ARGUMENT或Namelists想法如何做到这一点。
但是,如果您想每次重新编译它,可以使用预处理器来设置代码的某些部分。
请参见本示例代码:
PROGRAM area
IMPLICIT NONE
PRINT *, "area of circle with radius ", RADIUS, " is ",
& 3.15159 * RADIUS**2
END PROGRAM area
要使用预处理,你要么必须明确地告诉你的编译器做(gfortran -cpp
或ifort -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
虽然我现在有第二个想法告诉人们没有太多有关预处理程序的编程经验......他们可以有奇怪的效果... – chw21
教人们重新编译为每个不同的程序执行,这是一种*怪异效果* ... –
在案件我已经运行在其期望在一组的参数运行代码的参数分析,我在Python中使用Jinja2的模板库产生大量写了一个小脚本输入文件的数量。我选择了一个命名约定,使我能够轻松确定哪个输入文件对应哪个输入排列以帮助后处理结果。 Python &的具体用法Jinja2与输入生成脚本外部的文本模板不同,因此您可以在不编辑输入生成器的情况下对生成的文件进行调整。有很多成熟,简单的网页模板系统可以高效地生成输入文本文件。
输入参数和文件名之间的交叉引用可能与数据结构数组(如哈希或字典)中的索引一样简单。我尝试使用更有意义的内容,并为生成的输入添加描述性注释(假设输入格式允许注释...)
就我而言,我可能使用的代码不经过一个月的QA循环就无法重新编译,因此将参数化变体代码编写为单独的脚本比将其集成到单独的脚本要便宜得多我的Fortran代码。
我倾向于在Python中编写参数分析代码的另一个原因是因为它比在Fortran中编写复杂输入处理容易得多。能够使用numpy
来生成线性,对数或其他变体模式(例如Chebyshev节点)比在Fortran中尝试使用它容易得多。
标准免责声明:我的操作环境和用例可能与您的操作环境和用例非常不同,所以此技术可能不合适。我只是指出,这是一个具有几个优点的选项,具体取决于您的环境。
命令行参数的方法
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
注古代的编译器,你应该使用iargc
和getarg
代替。纯粹主义者会注意到这些是非标准的f77,然而它们通常在许多编译器中可用。
典型的Python脚本遍历参数列表:
import os
for r in (1.2,6.6): os.system('fortran_program %g'%r)
当然,你应该使用任何的脚本语言,你是舒服的
。我喜欢“高级”语言,因为我不可避免地似乎最终要在脚本中进行计算。
那么有些人会用他们最喜欢的脚本语言编写一个小脚本来为每个程序的执行提供一些输入参数。对于任何真实答案,请提出问题。 (不,您发布的内容不是问题。) –
您可能想要查找'Get_command_argument' – agentp
另一种选择是读取包含每次运行所需的输入参数的数据文件。 –