大约几年前,我对Fortran还是个新手,所以我过度使用了
SUBROUTINE
没有参数的,以及共享数据,因此这些过程对实际参数进行了计算,可通过
USE
声明。现在,我需要重用其中的一些过程(想想计算卷中的散度
大的
DIMENSION(:,:,:)
数组,从该卷中的向量场,3
大的
维度(:,:,:)
数组以派生类型粘合在一起),我想
-
保留它们
子例程
s但删除
使用
声明和使用
IN
/
OUT
/
INOUT
伪参数(简单),或
-
将其转换为
FUNCTION
s(因为我要学习一点,所以要努力一点)
我想这两种方法的性能可能会有所不同,我很想理解这一点。在接下来的MWE中,我编写了3个过程来进行相同的计算,但我不知道应该如何选择其中一个或其他;我也不知道其他方法是否更可取。
需要注意的是,我的程序中的所有秩3实际数组
ALLOCATABLE
必须如此。
PROGRAM mymod
IMPLICIT NONE
TYPE blk3d
REAL, DIMENSION(:,:,:), ALLOCATABLE :: values
END TYPE blk3d
TYPE(blk3d) :: A, B
INTEGER, PARAMETER :: n = 2
INTEGER :: i
ALLOCATE(A%values(n,n,n))
A%values = RESHAPE([(i/2.0, i = 1, PRODUCT(SHAPE(A%values)))], SHAPE(A%values))
print *, A%values
! 1st way
B = myfun(A)
print *, B%values
DEALLOCATE(B%values)
! 2nd way
ALLOCATE(B%values(n,n,n))
CALL mysub(A, B)
print *, B%values
DEALLOCATE(B%values)
! 3rd way
ALLOCATE(B%values(n,n,n))
CALL mysub2(A, B%values)
print *, B%values
CONTAINS
FUNCTION myfun(Adummy) RESULT(Bdummy)
IMPLICIT NONE
TYPE(blk3d), INTENT(IN) :: Adummy
TYPE(blk3d) :: Bdummy
ALLOCATE(Bdummy%values, mold = Adummy%values)
Bdummy%values(:,:,:) = 2*Adummy%values
END FUNCTION myfun
SUBROUTINE mysub(Adummy, Bdummy)
IMPLICIT NONE
TYPE(blk3d), INTENT(IN) :: Adummy
TYPE(blk3d), INTENT(INOUT) :: Bdummy
Bdummy%values(:,:,:) = 2*Adummy%values
END SUBROUTINE mysub
SUBROUTINE mysub2(Adummy, Bdummy)
IMPLICIT NONE
TYPE(blk3d), INTENT(IN) :: Adummy
REAL, DIMENSION(:,:,:), INTENT(OUT) :: Bdummy
Bdummy(:,:,:) = 2*Adummy%values
END SUBROUTINE mysub2
END PROGRAM mymod
编辑
在我的CFD程序中,我使用了几个排名3的大型阵列。这些数组在计算中相互作用(不仅仅是逐点的
+
/
-
/
*
,…)对其中一些对象执行,以获取其他对象。想想
B
其计算依据
A
通过示例中的4个过程之一,然后用于升级
A.
自身由
A = A + B
。我是否错误地认为上述4个选项可以完成相同的任务?从这个意义上说,我可以打电话
A = A + myfun(A)
如果我选择函数方法。
编辑2
实际的派生类型以及大的秩3数组有半打其他字段(标量和小的静态数组);此外,这种类型的大多数变量都是数组,
e、 g。
TYPE(blk3d), DIMENSION(n) :: A
。