3

我正在尝试编写一个程序,我希望可分配数组A的等级为 1、2 或 3,具体取决于我在运行时的输入。我想这样做是因为后续的操作A是相似的,并且我在一个模块中定义了一个work带有模块过程的接口,当它被执行时A,会给出所需的结果。

我目前正在做的是这样的:

program main
implicit none
integer :: rank,n=10
real*8, allocatable :: A1(:)
real*8, allocatable :: A2(:,:)
read (*,*) rank

if (rank.eq.1) then
    allocate (A1(n))
else if (rank.eq.2) then
    allocate (A2(n,n))
end if

! operate on the array
if (rank.eq.1) then
    call work(A1)
else if (rank.eq.2) then
    call work(A2)
end if

end program

如果我能以某种方式选择 的等级,事情会容易得多A,因为这样就if不需要这些陈述了。也许这是不可能的,但感谢所有帮助。

4

2 回答 2

4

将数组声明为排名第三。如果需要较低等级的数组,请将相关的尾随维度分配为大小为 1。

real, allocatable :: array(:,:,:)
...
select case (desired_rank)
case (1) ; allocate(array(n,1,1))
case (2) ; allocate(array(n,n,1))
case (3) ; allocate(array(n,n,n))
case default ; error stop 'bad desired rank'
end select

然后,您可以使用数组部分来获得array与所需排名一致的连续切片。或者,编写对数组进行操作的相关过程以获取 rank 3 参数,并让他们了解更高维度的 size one extent 的含义。

于 2016-06-27T20:09:36.700 回答
4

下一个 Fortran 标准 (2015) 的select rank结构类似于select case. 我的示例使用假设秩虚拟变量的内在select case构造。rank

    module my_type

  use, intrinsic :: iso_fortran_env, &
       ip => INT32, &
       wp => REAL64

  implicit none
  private
  public :: MyType

  type MyType
     real (wp)              :: rank0
     real (wp), allocatable :: rank1(:)
     real (wp), allocatable :: rank2(:,:)
     real (wp), allocatable :: rank3(:,:,:)
   contains
     procedure :: create => create_my_type
     procedure :: destroy => destroy_my_type
  end type MyType

contains

  subroutine create_my_type(this, array)
    ! calling arguments
    class (MyType), intent (in out) :: this
    real (wp),      intent (in)     :: array(..) !! Assumed-rank dummy variable

    ! local variables
    integer (ip), allocatable :: r(:)

    select case(rank(array))
    case (0)
       return
    case (1)
       r = shape(array)
       allocate( this%rank1(r(1)) )
    case (2)
       r = shape(array)
       allocate( this%rank2(r(1), r(2)) )
    case (3)
       r = shape(array)
       allocate( this%rank3(r(1), r(2), r(3)) )
    case default
       error stop 'array must have rank 0,1,2, or 3'
    end select

    ! Release memory
    if (allocated(r)) deallocate( r )

  end subroutine create_my_type


  subroutine destroy_my_type(this)
    ! calling arguments
    class (MyType), intent (in out) :: this

    if (allocated(this%rank1)) deallocate( this%rank1 )
    if (allocated(this%rank2)) deallocate( this%rank2 )
    if (allocated(this%rank3)) deallocate( this%rank3 )

  end subroutine destroy_my_type

end module my_type

program main

  use, intrinsic :: iso_fortran_env, only: &
       ip => INT32, &
       wp => REAL64

  use my_type, only: &
       MyType

  implicit none

  type (MyType) :: foo
  real (wp)     :: a0, a1(42), a2(42,42), a3(42,42,42)

  print *, rank(a0)
  print *, rank(a1)
  print *, rank(a2)
  print *, rank(a3)

  ! Allocate array of rank 3
  call foo%create(a3)

  print *, rank(foo%rank3)
  print *, shape(foo%rank3)
  print *, size(foo%rank3)

  ! Release memory
  call foo%destroy()

end program main
于 2016-06-27T18:07:01.513 回答