Fortran: Choosing the rank of an allocatable array

前端 未结 2 2021
萌比男神i
萌比男神i 2020-12-20 03:58

I am trying to write a program where I want the allocatable array A to be of either rank 1, 2, or 3, depending on my input at run-time. I want to do this since

2条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-20 04:36

    The next Fortran standard (2015) has the select rank construct similar to select case. My example uses the select case construct on the rank intrinsic of an assumed-rank dummy variable.

        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
    

提交回复
热议问题