【问题标题】:Pass external function with parameters in Fortran [duplicate]在Fortran中传递带有参数的外部函数[重复]
【发布时间】:2020-07-20 05:58:49
【问题描述】:

我最小的、可重现的示例如下所示:在我的程序mymain 中,我调用了一个子程序,该子程序有一个外部函数f1 和一个变量result 作为参数。在子例程中,函数完成了一些事情(对于这个例子,它只是在特定点被评估),结果通过参数result返回。

PROGRAM mymain

    IMPLICIT NONE

    REAL(KIND=8)    f1
    REAL(KIND=8)    result

    EXTERNAL f1


    CALL sub1(f1,result)

    PRINT *,result

END PROGRAM mymain

SUBROUTINE sub1(f1,result)

    IMPLICIT NONE

    REAL(KIND=8)                ::f1
    REAL(KIND=8), INTENT(OUT)   ::result
    REAL(KIND=8)                ::input

    EXTERNAL f1

    input=0.5

    result=f1(input)

END SUBROUTINE sub1

REAL(KIND=8) FUNCTION f1(x)

    REAL(KIND=8), INTENT(IN)    ::x
    REAL(KIND=8)                ::const

    const=1.

    f1=x**2+const

END FUNCTION f1

我的问题是我想从mymain 中更改函数f1 中的变量const

在我的实际问题中,子例程是 Fortran 库之一,它采用外部函数的积分,我需要多次调用此子例程,但始终在外部函数中使用不同的参数。

我不知道该怎么做,因为我不能像这样从mymain 调用子例程

CALL sub1(f1(x,const),result)

【问题讨论】:

    标签: fortran


    【解决方案1】:

    有几种方法可以实现您想要的,但我建议您学习使用 Fortran 的模块功能。这将允许您封装函数的信息。下面,我介绍两个模块。第一个用于为real 类型的 kind 类型参数设置一个命名常量。在您的代码中,当您使用 real(kind=8) 时,您使用的是编译器特定的值。第二个定义函数f(x)和设置const的方法

    !
    ! Set kind type parameter for double precision
    !
    module mytype
      implicit none
      integer, parameter :: dknd = kind(1.d0)
    end module mytype
    !
    ! Module defining the function
    !
    module fcn
     use mytype
     implicit none
     private                  ! Make everything private
     public f, set_const      ! Only allow access to f() and set_const().
     real(dknd) :: const = 0  ! Default constant value
     contains
       !
       ! Subroutine to set const.  Can be generalized to multiple constants.
       ! Call this prior to invoking f(x).
       !
       subroutine set_const(val)
         real(dknd), intent(in) :: val
         const = val
       end subroutine
       !
       ! Obviously, the function f(x)
       !
       function f(x)
         real(dknd) f
         real(dknd), intent(in) :: x
         f = x**2 + const
       end function f 
    end module fcn
    
    program mymain
      use fcn                  ! Use fcn to get access f and set_const
      use mytype               ! Use mytype to get access to dknd
      implicit none
      real(dknd) result
    
      call set_const(1._dknd)  ! Set const = 1
      call sub1(f, result)
      print *, result
    
      call set_const(2._dknd)  ! Set const = 2
      call sub1(f, result)
      print *, result
    end program mymain
    !
    ! Your subroutine.  DO NOT "USE FCN", here!
    !
    subroutine sub1(f1, result)
      use mytype                 ! Use mytype to get access to dknd
      implicit none
      real(dknd), external :: f1 ! f1 is external real(dknd) function
      real(dknd), intent(out) :: result
      real(dknd) input
      input = 0.5_dknd
      result = f1(input)
    end subroutine sub1
    

    【讨论】:

    • 首先:抱歉这么晚才回复,非常感谢!!我有几个简单的问题:我试图运行你的代码,我在sub1 中遇到了 2 个错误:real(dknd), intent(out) result 逗号后的“无效字符”和subroutine sub1(f1, result)“结果没有隐式类型”。我猜他们是相关的......
    • 再次抱歉,我刚刚在real(dknd), intent(out) result 行中添加了::,即:real(dknd), intent(out) :: result,现在一切正常!非常感谢你给了我一个准备好运行的代码,它有很好的文档记录!
    • 只是补充一点,如果您正在学习模块,最好(事实上,如果我的学生不这样做,我会让他们失败)将子例程 sub 放在一个模块中,以防止各种常见的编程错误,并使用接口块来声明函数,以防止相同的错误
    • @IanBush 谢谢!我会调查的。问题是示例中的子程序实际上是我从我没有编码的库中调用的子程序。但是您的评论非常有用,因为我真的需要学习 fortran。所以我会研究模块和接口!
    • 哎呀,很抱歉答案中缺少::。奇怪的是我编译并测试了代码。一定在翻译中丢失了。现已修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多