首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用interface将函数作为参数传递给子例程在Plato Fortran 90中不起作用

使用interface将函数作为参数传递给子例程在Plato Fortran 90中不起作用
EN

Stack Overflow用户
提问于 2014-09-21 13:39:32
回答 2查看 1.1K关注 0票数 2

我创建了一个fortran 90程序,在linux机器上使用,并使用gfortran编译。它在带有gfortran的linux机器上运行良好,但提供了错误。

error 327 - In the INTERFACE to SECANTMETHOD (from MODULE SECMETH), the ninth dummy argument (F) was of type REAL(KIND=2) FUNCTION, whereas the actual argument is of type REAL(KIND=2)

当使用柏拉图编译器(FTN95)时。有人知道我需要如何更改代码才能在柏拉图中工作吗?我试图阅读这个错误,有一些关于指针的提及,但从我尝试的情况来看,这并不起作用。我已经想出了一些变通方法,但是它们使得子例程不能再接受任何函数作为参数-这几乎是无用的。任何帮助都将不胜感激。我的代码如下。

代码语言:javascript
复制
!--! A module to define a real number precision.
module types
  integer, parameter :: dp=selected_real_kind(15)
end module types

module secFuncs
  contains

  function colebrookWhite(T)
    use types

    real(dp) :: colebrookWhite
    real(dp), intent(in) :: T

    colebrookwhite=25-T**2

    return
  end function colebrookWhite
end module secFuncs

module secMeth
  contains

  subroutine secantMethod(xolder,xold,xnew,epsi1,epsi2,maxit,exitFlag,numit,f)
    use types
    use secFuncs
    implicit none

    interface
      function f(T)
        use types
        real(dp) :: f
        real(dp), intent(in) :: T
      end function f
    end interface

    real(dp), intent(in) :: epsi1, epsi2
    real(dp), intent(inout) :: xolder, xold
    real(dp), intent(out) :: xnew
    integer, intent(in) :: maxit
    integer, intent(out) :: numit, exitFlag
    real(dp) :: fxold, fxolder, fxnew
    integer :: i

    fxolder = f(xolder)
    fxold = f(xold)

    i = 0

    do
      i = i + 1

      xnew = xold - fxold*(xold-xolder)/(fxold-fxolder)

      fxnew = f(xnew)

      if (i == maxit) then
        exitFlag = 1
        numit = i
        return
      else if (abs(fxnew) < epsi1) then
        exitFlag = 2
        numit = i
        return
      else if (abs(xnew - xold) < epsi2) then
        exitFlag = 3
        numit = i
        return
      end if

      xolder = xold
      xold = xnew
      fxolder = fxold
      fxold = fxnew
    end do
  end subroutine secantMethod

end module secMeth

program secantRoots
  use types
  use secMeth
  use secFuncs
  implicit none

  real(dp) :: x1, x2, xfinal, epsi1, epsi2
  integer :: ioerror, maxit, numit, exitFlag

  do
    write(*,'(A)',advance="no")"Please enter two initial root estimates, 2epsi's, and maxit: "
    read(*,*,iostat=ioerror) x1, x2, epsi1, epsi2, maxit

    if (ioerror /= 0) then
      write(*,*)"Invalid input."
    else
      exit
    end if
  end do

  call secantMethod(x1,x2,xfinal,epsi1,epsi2,maxit,exitFlag,numit,colebrookWhite)

  if (exitFlag == 1) then
    write(*,*)"The maximum number of iterations was reached."
  else if (exitFlag == 2) then
    write(*,'(a,f5.3,a,i3,a)')"The root is ", xfinal, ", which was reached in ", numit, " iterations."
  else if (exitFlag == 3) then
    write(*,'(a,i3,a)')"There is slow or no progress at ", numit, " iterations."
  end if

end program secantRoots
EN

回答 2

Stack Overflow用户

发布于 2014-09-21 14:07:24

Current gfortran在调用secantMethod过程时检测到错误,在这个过程中,colebrookWhite函数名后面有圆括号,但没有参数列表。

如果您想将一个函数作为参数传递(与计算函数的结果相反),这就是您在这里要做的事情,您不需要在函数名后面加上括号对。

代码语言:javascript
复制
call secantMethod(x1,x2,xfinal,epsi1,epsi2,maxit,exitFlag,numit,colebrookWhite )
!                                                                             ^
票数 2
EN

Stack Overflow用户

发布于 2014-09-22 10:02:34

我最终从Plato切换到Geany IDE (实际上我更喜欢Geany,因为我已经使用了几个小时),用Geany设置gfortran,并且代码可以与该设置一起工作。我猜我得到这个错误的原因是柏拉图的编译器实际上是一个fortran95编译器,而gfortran是一个fortran90编译器。我花了一段时间才让一切正常工作,但一旦我下载了gfortran的mingw-w64,并将path user (而不是system)环境变量设置到正确的位置,一切都会正常工作。我仍然有兴趣看看是否有一种方法可以让代码与FTN95编译器一起工作,但最终我仍然坚持使用gfortran和Geany。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25956179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档