沿所有维度存储要操作的多维数组



前言

我正在编写的Fortran程序应该根据ndims处理1D、2D和3D问题,CCD_1可以是1、2或3,并且是从输入文件中读取的。

在这些情况下,感兴趣的数量可以存储在阵列中(一个可以被命名为phi(

  1. 3(ALLOCATABLE(:)ALLOCATABLE(:,:)ALLOCATABLE(:,:,:)(
  2. 或者在秩3的阵列中(ALLOCATABLE(:,:,:),其中第三维度在2D中被设置为等于1,或者第二维度和第三维度两者在1D中都等于1(

这两种情况在这个答案中都得到了很好的解释。第一种方法对我来说似乎更优雅,但在下面我假设第二种方法,它肯定更简单。

这些量必须由沿着ndims维度的几个子程序(例如mysub(来操作(沿着"铅笔"应该给出一个图形概念(,所以我应该称之为

SELECT CASE (ndims)
! 3D case
CASE (3)
  DO j = ...
    DO k = ...
      CALL mysub(phi(:,j,k))
    END DO
  END DO
  DO i = ...
    DO k = ...
      CALL mysub(phi(i,:,k))
    END DO
  END DO
  DO i = ...
    DO j = ...
      CALL mysub(phi(i,j,:))
    END DO
  END DO
! 2D case
CASE (2)
  DO j = ...
    DO k = ...
      CALL mysub(phi(:,j,1))
    END DO
  END DO
  DO i = ...
    DO k = ...
      CALL mysub(phi(i,:,1))
    END DO
  END DO
! 1D case
CASE (1)
  DO j = ...
    DO k = ...
      CALL mysub(phi(:,1,1))
    END DO
  END DO
END SELECT

实际问题

有人能建议我(或帮助我设计!(一种不同的存储phi的方法吗?(可能涉及派生数据类型?(这样我就可以按如下方式折叠前面的代码了?

DO id = 1, ndims
  CALL mysub2(phi,id)
END DO

(此处mysub2作用于mysub的位置。(

所以问题是我应该如何存储phi,以便用第二个代码替换第一个代码?

也许我可以回到前言,决定遵循第1点,在这种情况下,编写通用接口会更容易。我认为,这只是一种"隐藏"SELECT CASE的确切功能的方法。两者(SELECT CASE/通用INTERFACE(中的哪一个更有效?

面对这个问题,只有这两种方法吗?

也许我误解了,但我认为具体问题的答案是根本不更改phi的存储或声明。

在原始代码中,三维数据(区分数据的秩和用于存储数据的数组的秩(是沿着第一维度、第二维度、第三维度分片处理的。二维数据沿第一条处理,然后沿第二条处理,而一维数据仅沿第一条进行处理。

因此,当id从1到数据中的维数时,考虑以下mysub2的实现:

SUBROUTINE mysub2(phi, id)
  TYPE(pink_elephant), INTENT(IN) :: phi(:,:,:)
  INTEGER, INTENT(IN) :: id
  INTEGER :: i, j, k
  SELECT CASE (id)
  CASE (1)
    DO j = ...
      DO k = ...
        CALL mysub(phi(:,j,k))
      END DO
    END DO
  CASE (2)
    DO i = ...
      DO k = ...
        CALL mysub(phi(i,:,k))
      END DO
    END DO
  CASE (3)
    DO i = ...
      DO j = ...
        CALL mysub(phi(i,j,:))
      END DO
    END DO
  END SELECT
END SUBROUTINE mysub2

~~

泛型接口总是可以在"编译时"解析——特定CALL语句或函数引用将调用的特定过程(非类型绑定(或绑定(类型绑定(可以通过查看代码中的声明来确定。

如果你有一种情况,"运行时"信息将影响过程的选择,那么除了通用的解析之外,还必须有一些其他可执行机制发挥作用——If语句、select case、动态调度等。

因此,询问通用解决方案是否比可执行决策更有效并没有特别的意义——它们是不同的。

您可能想要这样的东西:

program test
   integer :: j,ndims
   integer :: n ! rank of each dimension, could also be read from input an allocated separately
   type arr
      real(8) :: x(n) ! one array for each dimension
   end type
   type(arr),allocatable :: phi
   read(*,*) ndims
   allocate(phi(ndims))
   do j=1,ndims
      call mysub(phi(j)%x) ! acts on the array in dimension j
   end do
contains
   subroutine mysub(x)
   ...
   end subroutine
end program

相关内容

  • 没有找到相关文章

最新更新