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

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

问题描述

我希望我的代码将代码写入另一个文档中,读取它,然后像使用代码编写代码一样使用它。假设我们有以下内容:
$ b $ pre $ MODULE samplemod
CONTAINS
FUNCTION sillysum(boudary,function)RESULT(计数器)
IMPLICIT NONE
REAL(KIND = 8):: boundary,counter
REAL(KIND = 8),DIMENSION(:) :: function
INTEGER :: m
计数器= 0.d0
DO m = 1,my_mesh%me
计数器=函数(m)+外部函数
END DO
END FUNCTION sillysum
END MODULE samplemod

程序sampleprogram
USE samplemod
REAL(KIND = 8),DIMENSION(:) :: function1
ALLOCATE(function1(100))
DO m = 1,100
函数1(i)= i
END DO
WRITE(*,*)sillysum(100,function1)
结束程序sampleprogram

在某些外部文件(例如'externfunct.txt')中写入 m ** 2 。 Fortran代码如何读取外部函数 m ** 2 SIN(m),甚至 0 并替换 externalfunction 。这里有一个简单的例子:

  REAL(KIND = 8):: x = 2 
CHARACTER(LEN = *) :: strng =external
WRITE(*,*)Hello world,2 +,strng,=,2 + external

在我写的txt文件中,我写了 SIN(x)

解决方案

我认为这有两种不同的方法(*实际上,似乎还有一种第三种方法,请参阅EDIT)。一个是使用共享库,另一个是使用数学表达式的解析器。第一种方法在Rossetastone页面(调用共享库中的函数)和SO页面(例如, Fortran动态库,在运行时加载?)。对于第二种方法,您可以通过使用数学解析器或Fortran数学解析器等进行搜索来查找第三方库。在此,我尝试了这一个因为它看起来非常简单(只有一个模块,没有安装)。如果我们编写一个简单的测试程序,像这样:

 程序测试
只使用解释器:init,evaluate,dp = > realkind
隐式无
整型,参数:: mxvars = 10! (10):: symbols(mxvars)
real(dp):: values(mxvars),回答
字符(1000):: funcstr !!用户定义的数学表达式
character(5):: stat

!>定义变量名称。
符号(1)=x
符号(2)=a
符号(3)=b
符号(4)=c
符号(5)=foo

!>获取数学表达式。
print *,请输入一个数学表达式:
read(*,(a))funcstr !!例如a * x + b

!>初始化评估者。
调用init(funcstr,symbols,stat)
if(stat / =ok)stopstat / = ok

!>设置变量的值。
值(:)= 0
值(1)= 2.0_dp! x
值(2)= 10.0_dp!
值(3)= 7.0_dp! b

!>评估。
answer = evaluate(values)
print *,function value =,answer

end program
 $ gfortran -ffree- line-length-none interpreter.f90 mytest.f90 

我们可以按如下方式测试各种表达式: p>

  $ ./a.out 
请输入数学表达式:
a * x + b
函数值= 27.000000000000000
$ ./a.out
请输入数学表达式:
sin(a * x)+ cos(b)+ foo
函数值= 1.6668475050709324

其他库的用法也非常相似。由于每个库的性能可能会有所不同,因此尝试使用几个不同的库进行比较可能会很有用。






( * 1)模块有一些行 sind cosd tand ,但它们不被gfortran支持。所以,为了编译,我已经将它们注释掉了,并用 stop 替换它们,即

  stopsind not supported ...
! pdata(st)= sind(pdata(st))

sind(x)意味着 sin(x * pi / 180),所以可以这样定义它。)








第三种方法可能是调用通过 system()来内置 eval()函数,如Python或Julia等解释型语言,例如这个SO页面。虽然这也有很多弱点(并且可能直接使用这些语言更容易),但是从Fortran调用 eval()可能对于某些特定用途很有用。

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

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

Where in a txt file I have written I have written SIN(x).

解决方案

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

and compile it as (*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) 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))

(I guess sind(x) means sin( x * pi / 180 ), so it may be OK to define it as such.)


[EDIT]

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天全站免登陆