首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将故障诊断灯作为模块包含在内

将故障诊断灯作为模块包含在内
EN

Stack Overflow用户
提问于 2020-11-12 04:19:48
回答 1查看 178关注 0票数 0

我正在尝试将QUADPACK集成到我的Fortran90代码中。我尝试在我的主文件中调用子例程,但它工作得很好。

为了不把我的主文件弄得乱七八糟,我试着把代码的集成部分移到一个模块中。然而,当我把我的模块写成

代码语言:javascript
复制
module integrate 

   use ...

   call dqage(params..)

contains 

   functions

end module 

我收到以下消息

代码语言:javascript
复制
Unexpected CALL statement in MODULE at (1).

我从另一篇文章中了解到,从模块进行这样的调用是违反Fortran标准的。因此,我尝试将故障诊断包代码封装到一个模块中,认为这会有所帮助。它没有像现在一样,我在编译时得到以下错误

代码语言:javascript
复制
/usr/bin/ld: quadpack_double.o: in function `__quadpack_MOD_dqc25s':
quadpack_double.f90:(.text+0xce29): undefined reference to `dqwgts_'

所以,我的问题是,我如何集成QUADPACK,以便我可以在主文件之外的其他地方使用它?

EN

回答 1

Stack Overflow用户

发布于 2020-11-12 16:48:10

您需要编译所有故障诊断包文件并链接到它们。

一个用于连接故障诊断例程的模块将使您的编程工作更加轻松。下面的模块展示了一种方法

代码语言:javascript
复制
module quadpack_m
  use, intrinsic :: ieee_arithmetic
  implicit none

  private
  public :: QUADPACK_ERROR, quadpack_int

  interface
    function quadpack_integrand(x) result(f)
      real, intent(in) :: x
      real             :: f
    end function
  end interface

  character(*), parameter :: QUADPACK_ERROR(6) = [ &
    "maximum number of subdivisions achieved",     &
    "roundoff error detected                ",     &
    "extremely bad integrand behaviour      ",     &
    "algorithm does not converge            ",     &
    "integral is probably divergent         ",     &
    "input is invalid                       "      &
  ]

  external :: dqags, dqagi

contains

  subroutine quadpack_int(f, a, b, atol, rtol, result, aerr, neval, ier, limit, last)
    procedure(quadpack_integrand)  :: f
      !! function to integrate
    real,              intent(in)  :: a
      !! lower integration limit
    real,              intent(in)  :: b
      !! upper integration limit
    real,              intent(in)  :: atol
      !! absolute tolerance
    real,              intent(in)  :: rtol
      !! relative tolerance
    real,              intent(out) :: result
      !! output result of integration
    real,    optional, intent(out) :: aerr
      !! optional: output estimate of the modulus of the absolute error, which should equal or exceed abs(i-result)
    integer, optional, intent(out) :: neval
      !! optional: output number of integrand evaluations
    integer, optional, intent(out) :: ier
      !! optional: output error code
    integer, optional, intent(in)  :: limit
      !! optional: maximum number of subintervals (default: 4096)
    integer, optional, intent(out) :: last
      !! optional, output number of subintervals used

    ! local variables
    integer              :: neval_, ier_, limit_, lenw, last_, inf
    integer, allocatable :: iwork(:)
    real                 :: aerr_, bnd
    real,    allocatable :: work(:)
    logical              :: a_inf, b_inf

    limit_ = 4096
    if (present(limit)) limit_ = limit
    lenw = limit_ * 4

    allocate (iwork(limit_), work(lenw))

    a_inf = (ieee_class(a) == IEEE_NEGATIVE_INF)
    b_inf = (ieee_class(b) == IEEE_POSITIVE_INF)

    bnd = 0
    if (a_inf .and. b_inf) then
      inf = 2
    elseif (a_inf) then
      bnd = b
      inf = -1
    elseif (b_inf) then
      bnd = a
      inf = +1
    else
      inf = 0
    end if

    if (inf == 0) then
      call dqags(f, a,   b,   atol, rtol, result, aerr_, neval_, ier_, limit_, lenw, last_, iwork, work)
    else
      call dqagi(f, bnd, inf, atol, rtol, result, aerr_, neval_, ier_, limit_, lenw, last_, iwork, work)
    end if

    if (present(aerr )) aerr  = aerr_
    if (present(neval)) neval = neval_
    if (present(ier  )) ier   = ier_
    if (present(last )) last  = last_
  end subroutine

end module

请注意,此代码假定在默认情况下编译为8字节的浮点数/整数,例如$ ifort -i8 -real-size 64$ gfortran -fdefault-integer-8 -fdefault-real-8。如果可移植性是一个重要的问题,那么就不应该使用这些编译选项,而应该使用iso_fortran_env来指定数据类型,即INT64, REAL64

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

https://stackoverflow.com/questions/64793582

复制
相关文章

相似问题

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