如何将外部文件中的 fortran 代码插入单独的代码中? [英] How does one insert fortran code from an external file into a separate code?
问题描述
我想让我的代码获取写在另一个文档中的代码,阅读它,然后像在代码中一样使用它.假设我们有以下内容:
I'd like to have my code take code written in another document, read it, and then use it as though it was written in the code. Say we have the following:
MODULE samplemod
CONTAINS
FUNCTION sillysum(boudary,function) RESULT(counter)
IMPLICIT NONE
REAL(KIND=8) :: boundary, counter
REAL(KIND=8), DIMENSION(:) :: function
INTEGER :: m
counter = 0.d0
DO m = 1, my_mesh%me
counter = function(m) + externalfunction
END DO
END FUNCTION sillysum
END MODULE samplemod
PROGRAM sampleprogram
USE samplemod
REAL(KIND=8), DIMENSION(:) :: function1
ALLOCATE(function1(100))
DO m=1, 100
function1(i) = i
END DO
WRITE(*,*) sillysum(100,function1)
END PROGRAM sampleprogram
在一些外部文件(比如'externfunct.txt')中,有人写了m**2
.Fortran 代码如何读取外部函数 m**2
、SIN(m)
甚至 0
并将其替换为 外部函数
.这是一个更简单的例子:
Where in some external file (say 'externfunct.txt') one has written m**2
. How can the Fortran code read the external function m**2
, SIN(m)
, or even 0
and have that replace externalfunction
. Here's a simpler example:
REAL(KIND=8) :: x = 2
CHARACTER(LEN=*) :: strng = "external"
WRITE(*,*) "Hello world, 2 + ", strng, " = ", 2 + external
在我写的 txt 文件中我写了 SIN(x)
.
Where in a txt file I have written I have written SIN(x)
.
推荐答案
我认为有两种不同的方法(* 事实上,似乎还有第三种"方法,请参阅编辑);一种是使用共享库,另一种是使用解析器进行数学表达式.第一种方法在 Rossetastone 页面(在共享库中调用函数)和 SO 页面中进行了描述(Fortran 动态库,在运行时加载?),例如.对于第二种方法,您可以通过使用数学解析器"或Fortran 数学解析器"等搜索来找到第三方库.在这里,我尝试了 这个 因为它看起来很简单(只有一个模块,没有安装).如果我们像这样写一个简单的测试程序
I think there are two different approaches for this (* in fact, there seems a "third" approach also, see EDIT); one is to use a shared library, and the other is to use a parser for math expressions. The first approach is described in a Rossetastone page (Call a function in a shared library) and an SO page (Fortran dynamic libraries, load at runtime?), for example. For the second approach, you can find 3rd-party libraries by searching with "math parser" or "Fortran math parser" etc. Here, I have tried this one because it seems pretty simple (only one module and no installation). If we write a simple test program like this
program test
use interpreter, only: init, evaluate, dp => realkind
implicit none
integer, parameter :: mxvars = 10 !! consider 10 variables at most here
character(10) :: symbols( mxvars )
real(dp) :: values( mxvars ), answer
character(1000) :: funcstr !! a user-defined math expression
character(5) :: stat
!> Define variable names.
symbols( 1 ) = "x"
symbols( 2 ) = "a"
symbols( 3 ) = "b"
symbols( 4 ) = "c"
symbols( 5 ) = "foo"
!> Get a math expression.
print *, "Please input a math expression:"
read(*, "(a)") funcstr !! e.g., a * x + b
!> Init the evaluator.
call init( funcstr, symbols, stat )
if ( stat /= "ok" ) stop "stat /= ok"
!> Set values for the variables.
values( : ) = 0
values( 1 ) = 2.0_dp ! x
values( 2 ) = 10.0_dp ! a
values( 3 ) = 7.0_dp ! b
!> Evaluate.
answer = evaluate( values )
print *, "function value = ", answer
end program
编译成(*1)
$ gfortran -ffree-line-length-none interpreter.f90 mytest.f90
我们可以测试各种表达式如下:
we can test various expressions as follows:
$ ./a.out
Please input a math expression:
a * x + b
function value = 27.000000000000000
$ ./a.out
Please input a math expression:
sin( a * x ) + cos( b ) + foo
function value = 1.6668475050709324
其他库的用法似乎也很相似.由于每个库的性能可能有很大差异,因此尝试几个不同的库进行比较可能会很有用.
The usage of other libraries also seems very similar. Because the performance of each library may be rather different, it may be useful to try several different libraries for comparison.
(*1) 该模块有一些带有 sind
、cosd
和 tand
的行,但 gfortran 不支持它们.因此,为了编译,我将它们注释掉并用 stop
替换它们,即
(*1) The module has some lines with sind
, cosd
, and tand
, but they are not supported by gfortran. So, to compile, I have commented them out and replaced them by stop
, i.e.,
stop "sind not supported..."
! pdata(st) = sind(pdata(st))
(我猜sind(x)
的意思是sin(x * pi/180)
,所以这样定义可能没问题.)
(I guess sind(x)
means sin( x * pi / 180 )
, so it may be OK to define it as such.)
第三种"方法可能是通过 system()
在 Python 或 Julia 等解释型语言中调用内置的 eval()
函数,例如 eval()
可能对某些特定目的有用.
A "third" approach may be to call the built-in eval()
function in interpreted languages like Python or Julia via system()
, e.g., this SO page. Although this also has a lot of weak points (and it is probably much easier to use such languages directly), calling eval()
from Fortran might be useful for some specific purposes.
这篇关于如何将外部文件中的 fortran 代码插入单独的代码中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!