使用 Fortran 可分配数组时如何模拟等效性

Pie*_*rre 6 arrays fortran pointers transfer equivalence

我在 Fortran 例程中有 3 个可分配的一维数组,VX(:)、VY(:)、VZ(:),它们都具有相同的大小。

我需要将它们聚合在一个名为 VARXYZ 的二维数组中,并将其发送到修改“矩阵”的例程。下面的代码可以工作,但会强制将内存大小加倍

      SUBROUTINE TEST(VX,VY,VZ)
      REAL(8), INTENT(INOUT), DIMENSION(:) :: VX,VY,VZ ! They've been allocated with size N in the main
      REAL(8), ALLOCATABLE, DIMENSION(:,:) :: VARXYZ   ! The 'matrix'

      ALLOCATE(VARXYZ(3,N))

      VARXYZ(1,:)=VX(:)
      VARXYZ(2,:)=VY(:)
      VARXYZ(3,:)=VZ(:)
      
      CALL CHANGE_MATRIX(VARXYZ)

      VX(:)=VARXYZ(1,:)
      VY(:)=VARXYZ(2,:)
      VZ(:)=VARXYZ(3,:)
      ...
Run Code Online (Sandbox Code Playgroud)

为了避免“双重分配”,我的第一个错误反应是在一维数组和矩阵的 3 个“列”之间使用 EQUIVALENCE,但显然这是不允许的。

经过一番阅读后,我看到有人推荐使用指针和 TRANSFER 内部函数,但我不知道如何在这里使用它们。

您能否举例说明如何模仿我需要的这种等效机制?

fra*_*lus 1

不可能完全按照你想要的方式去做,但是对更高层的结构进行改变是可能的。

三个输入数组vxvyvz是简单连续的,但并不期望这三个数组一起形成一个(简单)连续的内存块。特别是,这意味着诸如使用 EQUIVALANCE 之类的存储关联机制无法工作。(也明确禁止可分配对象和虚拟参数作为等价对象出现,但前面的参数表明解决此问题是徒劳的。)

更广泛地说,指针不能指向任意 内存块

最后,transfer是一种通过转移的物理表示创建新实体的方法:它是一个副本。

您也许可以向后工作,通过确保您的三个数组本身是较大的三维数组的列,但您不能从过程test本身强制执行此操作。但请注意,test在这种情况下您需要进行更改:可分配的数组虚拟参数必须与可分配的实际数组虚拟参数相对应:较大数组的部分永远不会。(但是,这个示例似乎并不依赖于虚拟参数的可分配性质。)