如何将外部文件中的 fortran 代码插入单独的代码中? [英] How does one insert fortran code from an external file into a separate code?

查看:29
本文介绍了如何将外部文件中的 fortran 代码插入单独的代码中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的代码获取写在另一个文档中的代码,阅读它,然后像在代码中一样使用它.假设我们有以下内容:

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**2SIN(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) 该模块有一些带有 sindcosdtand 的行,但 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() 函数,例如 此 SO 页面.虽然这也有很多弱点(直接使用这些语言可能更容易),但从 Fortran 调用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆