3

我使用 python 作为模型中几个 fortran 文件的接口。我想多次复制一个 fortran 文件,但在每次复制时,我都会更改描述我的模型的参数。

例如:我有下面的fortran文件

!file.f
! This is a fortran code

!Parameters
alpha = 0.5
beta = 100
...

我想复制 file.f 几次,这样我就有 file1.f、file2.f、file3.f 等。但是,在每个复制的文件中,我想自动更改参数 alpha 和 beta。谢谢

编辑:让我进一步解释一下。我正在使用 python 对已经在 fortran 中开发的模型实现数据同化(卡尔曼滤波)。基本上,它的工作原理是在每个指定的时间步,fortran 模型停止运行,然后我将现实世界的数据集成到模型数据中,并在 python 中执行此操作。然后在集成(同化)之后,我重新运行相同的模型,但是这次使用的是我从融合来自模型和观察的数据以及新的初始条件中获得的新参数。除了运行由 fortran 完成的模型之外,我使用 python 来做所有事情。

4

4 回答 4

4

我认为最一致的方法是使用模板引擎。Python 有很多,通常部署在 Web 应用程序中。

但是模板引擎的目的恰恰是让一个人拥有大部分代码,不需要像静态文本一样更改,并通过一些特殊的标记插入 Python 代码中生成的变量。

根据参数的复杂性,您甚至可能根本不需要任何单独的模板引擎,只需继续使用 Python 字符串格式化功能,如下面的示例所示。

模板引擎可以为您提供一些额外的容量,例如在模板内展开循环和条件的能力。

示例 - 编写您的 fortram 模板,如下所示:

!file.f
! This is a fortran code

!Parameters
alpha = %(alpha)s
beta = %(beta)s

在 Python 代码中,编写如下内容:

template = open("fortram_template.for", "rt").read()
data = {"alpha": 0.5, "beta": 100}

with open("fortram_1.for", "wt") as output:
    output.write (template % data)
于 2012-01-13T02:10:09.413 回答
2

这是您可以执行的操作的示例。我已经在列表中放置了各种(alpha,beta)对alpha_beta。我选择使用alpha_beta对位置的索引作为增加文件名的值,但是有多种方法可以做到这一点。这段代码很脆弱,因为它对您的 .f 文件进行了很多假设,但由于这是供您个人在生成这些文件时使用的,所以我认为您会没事的(例如,根据您提供的信息,我假设有文件中一行的开头只有一个单词 alpha 的实例 - 如果不是这样,您可能最好使用正则表达式)。

alpha_beta = [(0.1, 16), (0.9, 50), (0.4, 76)]
file_name = 'file'
file_ext = '.txt'

for index, vars in enumerate(alpha_beta, start=1):
    with open(file_name + file_ext) as f:
        alpha, beta = vars
        new_file = open(file_name + str(index) + file_ext, 'w')
        for line in f:
            if line.startswith('alpha'):
                new_file.write('alpha = %s \n' % str(alpha))
            elif line.startswith('beta'):
                new_file.write('beta = %s \n' % str(beta))
            else:
                new_file.write(line)
        new_file.close()
于 2012-01-13T02:13:19.993 回答
2

Fortran 解决方案可能是将参数行写入单独的文本文件,然后include在 Fortran 源文件中使用如下行写入该文件:

include 'parameters.inc'

这样您就可以简单地重新生成参数文件,而无需接触包含主要 Fortran 代码的文件。

于 2012-01-13T02:20:53.693 回答
1

首先,正如几条评论中所述,我认为这种解决方案过于矫枉过正。如果您不会进行大量 fortran 编码,我会选择以下两个选项之一,最好是第二个选项。

  1. 从临时输入文件中读取要使用的参数,例如:

    !file.f
    !This is a fortran code
    
    !Parameters
    open (unit=input, file='tmp_inp.txt', action='read', iostat=ierr)
    read (input, '(...)') alpha, beta
    

    然后从 Python 或使用 sed 更改临时输入文件中的值。

  2. 通过使用 f2py 将 fortran 代码与 python 连接,将参数作为参数从 python 中传递给 fortran 子例程。fortran 代码如下所示:

    !file.f
    !This is a fortran code
    subroutine my_sub(alpha, beta)
    ...
    

    然后用 f2py 编译:

    f2py -c -m my_fortran_code file.f
    

    最后从 python 内部调用:

    #python code
    from my_fortran_code import my_sub
    my_sub(alpha, beta)
    

这两种解决方案都不需要您为了更改一些输入参数而重新编译任何 fortran 代码。

于 2012-01-13T06:43:05.387 回答