fortran - 在 FORTRAN 子例程中传递不同的变量集

标签 fortran

我想应用三种不同的方法,使用整数开关的值进行选择。第一种方法使用两个整数,第二个方法使用实数数组和一个整数,第三个方法使用实数二维数组。在我当前的实现中,我分配并传递上述所有数据(2 int + real_array + int + real_2array)作为参数。我也可以使用一个模块,但它是相似的。我正在寻找一种方法来仅定义我的方法将使用的数据(即仅定义方法 3 的矩阵),而不定义其他数据。有什么建议吗?

编辑:
我已经制作了上述内容的简化版本。
主程序部分内容:

  INTEGER                             :: m, imeth
  REAL*8                              :: x, y
  REAL*8, DIMENSION(:), ALLOCATABLE   :: uu, wc
  REAL*8, DIMENSION(:,:), ALLOCATABLE :: BCH

  imeth = 0
  m = 64
  ALLOCATE(uu(m), uu_(m), wc(m))
  ALLOCATE(BCH(m,m))

  if (imeth .EQ. 0) then
     x = 1.0d0
     y = 2.0d0
  elseif (imeth .EQ. 1) then
     !Assign values to wc
  else
     !Assign values to BCH
  endif

  call subr(m,x,y,uu,uu_,imeth,BCH,wc)

  STOP
  END

和一个子程序

  SUBROUTINE subr(n,a,b,u,u_,imeth,DCH,ws)
  IMPLICIT NONE
  INTEGER,  INTENT(IN)  :: n, imeth
  REAL*8,   INTENT(IN)  :: u(n), DCH(n,n), ws(n)
  REAL*8,   INTENT(OUT) :: u_(n)
  INTEGER              :: i

  if (imeth .EQ. 0) then
     u_ = -u_ * 0.5d0 / (a+b)
  elseif (imeth .EQ. 1) then
     u_ = -u / ws
  else
     u_ = matmul(DCH,u)
  endif

  RETURN
  END SUBROUTINE subr

我希望主程序有这样的形式

  imeth = 0
  m = 64
  ALLOCATE(uu(m), uu_(m))


  if (imeth .EQ. 0) then
     a = 1.0d0
     b = 2.0d0
  elseif (imeth .EQ. 1) then
     ALLOCATE(wc(m))
     !Assign values to wc
  else
     ALLOCATE(BCH(m,m))
     !Assign values to BCH
  endif

  if (imeth .EQ. 0) then
     call subrA(m,x,y,uu,uu_)
  elseif (imeth .EQ. 1) then
     call subrB(m,wc,uu,uu_)
  else
     call subrC(m,BCH,uu,uu_)
  endif

最佳答案

编辑:OP 添加代码后,我认为将 可选 参数与 present 内在函数结合使用可能更适合此任务。然后子例程可以读取

SUBROUTINE subr(n,u_,a,b,u,DCH,ws)
  IMPLICIT NONE
  INTEGER,  INTENT(IN)           :: n
  REAL*8,   INTENT(OUT)          :: u_(n)
  REAL*8,   INTENT(IN),OPTIONAL  :: a(n)
  REAL*8,   INTENT(IN),OPTIONAL  :: b(n)
  REAL*8,   INTENT(IN),OPTIONAL  :: u(n)
  REAL*8,   INTENT(IN),OPTIONAL  :: DCH(n,n)
  REAL*8,   INTENT(IN),OPTIONAL  :: ws(n)
  INTEGER                        :: i

  if ( present(a) .and. present(b) ) then
     u_ = -u_ * 0.5d0 / (a+b)
  elseif ( present(u) .and. present(ws) ) then
     u_ = -u / ws
  elseif ( present(wch) .and. present(u) ) then
     u_ = matmul(DCH,u)
  else
     stop 'invalid combination'
  endif

END SUBROUTINE subr
<小时/>

这是旧答案,因为它仍然可能有帮助:

<小时/>

也许你可以尝试接口(interface):

module interface_test

  implicit none

  interface method
    module procedure method1
    module procedure method2
    module procedure method3
  end interface

contains

  subroutine method1(int1, int2)
    implicit none
    integer,intent(in)  :: int1
    integer,intent(out) :: int2

    int2 = 2*int1
  end subroutine

  subroutine method2(int, realArray)
    implicit none
    integer,intent(in)  :: int
    real,intent(out)    :: realArray(:)

    realArray = real(2*int)
  end subroutine

  subroutine method3(realArray)
    implicit none
    real,intent(inout)  :: realArray(:,:)

    realArray = 2*realArray
  end subroutine

end module

program test
  use interface_test, only: method
  implicit none
  integer :: int1, int2
  real    :: arr1D(10)
  real    :: arr2D(10,10)

  int1 = 1

  call method(int1, int2)
  print *, int2

  call method(int1,arr1D)
  print *, arr1D(1)

  arr2D = 1.
  call method(arr2D)
  print *, arr2D(1,1)
end program

关于fortran - 在 FORTRAN 子例程中传递不同的变量集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23662064/

相关文章:

multithreading - LAPACK 例程线程安全吗?

c++ - 如何找到库调用返回的位置?

module - 使用 waf 构建 fortran 库,安装 .mod 文件

r - "get_int_parms"不适用于包 "glmnet"的 .Fortran()

generics - 在 Fortran 90 中为抽象类型创建接口(interface)

compilation - Fortran 编译执行中不需要的回溯信息

fortran - 这在 Fortran : dot_product(x, x) 中合法吗?

python - Fortran 源代码但未找到 Fortran 编译器

fortran - 是否可以让 Fortran 源代码检测编译器标志?

python - 无法从 ctypes 获取 Fortran 函数输出