我有一些可分配的数组,我需要在一些子程序之间共享。我通常只是将它们作为参数传递或者可以在模块中写入所有内容,但我担心这在我的情况下是不可能的。
我只编写一些自己的子程序,并使用由FEM-Solver提供和描述的子程序。所以我不能改变这个子程序的参数或将它们包装在一个模块中。
据我所知,在编译时也无法使用未知大小的数组构建公共块。
还有别的东西要通过我的阵列吗?
更新:
目前我的程序环境如下:
我有一个由FEM程序提供的子程序,它在每次递增后调用,这会调用我的几个子程序,我为每个节点或其中一个子集计算一些值。
要在模拟后显示这些值,我必须将它们传递给另一个子程序。 FEM子解算器在增量结束时为每个节点调用该子程序。因此,将我的代码转移到此子例程会产生大量开销。
我的想法是计算一次值,将值存储在数组中并将此数组传递给第二个子例程,在那里它们将被写入计算数据库。
更新
一些伪代码:
假设程序行为:
Program FEM-solver
*magic*
call ENDINC(ar1,ar2)
*something*
do NodeID=1,Sum_Of_Nodes
do valueID=1,Sum_Of_User_Computed_Values !(defined in preprocessing)
call nodeval(NodeID,valueID,Value,ar3,...,arN)
end do
end do
*voodoo*
end program FEM-solver
写作和工作:
Subroutine ENDINC(ar1,ar2)
*Computation of some node values*
*Calling of own Subroutines, which compute more values*
*Writing an array with results values for some/each node(s)*
nodersltArr(NodeID,rslt)=*some Value*
end Subroutine ENDINC
需要将计算值写入节点解决方案数据库:
Subroutine nodeval(NodeID,valueID,Value,ar3,...,arN)
*called for each NodeID and valueID*
value=noderslArr(NodeID,valueID)
end subroutine nodeval
答案 0 :(得分:2)
只要在调用之前分配了数组,就可以将可分配数组传递给未声明为使用可分配数组的过程。 (当然,在没有该属性的情况下,您不能将该数组用作可分配数组。)或许这将解决您的问题。在您编写的代码中分配数组,而不是将其作为参数传递给FEM解算器。
示例代码:(我通常会将该函数放入模块中,但您说不能这样做,所以我写了一个示例,显示了不使用模块的情况。)
function MySum ( RegArray )
real :: MySum
real, dimension (:), intent (in) :: RegArray
MySum = sum (RegArray)
end function MySum
program TestArray
implicit none
interface AFunc
function MySum ( SomeArray )
real :: MySum
real, dimension (:), intent (in) :: SomeArray
end function MySum
end interface AFunc
real, dimension (:), allocatable :: AllocArray
integer :: N
real :: answer
write (*, '("Input array size: ")', advance="no")
read (*, *) N
allocate ( AllocArray (1:N) )
AllocArray = 1.0
answer = MySum ( AllocArray )
write (*, *) answer
end program TestArray
----------编辑:第二个概念---------
在两个子程序之间共享一个可分配的数组,而不需要调用例程“知道”该数组。
module MySubs
real, allocatable, dimension (:,:) :: array
contains
subroutine One ( x, y, ... N, M )
integer, intent (in) :: N, M
if ( .NOT. allocated (array) ) allocate ( array (N, M) )
end subroutine One
subroutine Two ( .... )
end subroutine Two
end module MySubs
更新:注意:此方法可用于在两个例程之间传递信息,而主程序无需访问模块...对于问题,而无需修改原始主要的prpgram。该示例的一部分是如何分配数组:该示例通过使用首先使用数组的子例程来测试数组是否已分配 - 如果不是,则分配数组。
答案 1 :(得分:1)
下面的三个例子都与gfortran有关。第二个可能在某些编译器上失败,因为它使用F2003功能(可分配的伪参数)和not all compilers are 100% F2003 compliant。但是,大多数实现ISO TR 15581(包括此功能)。
第一个版本,您可以使用指向可分配数组的公共指针。
program hip
implicit none
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
double precision, allocatable, dimension(:, :), target :: a
allocate(a(100, 100))
a(1, 1) = 3.1416d0
p => a
call hop
deallocate(a)
end program
subroutine hop
implicit none
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
print *, size(p, 1), size(p, 2), p(1, 1)
end subroutine
第二个版本,在子程序中分配然后调用另一个。还需要在主程序中声明数组。
program hip
implicit none
interface
subroutine hip_alloc(arr)
double precision, allocatable, dimension(:, :) :: arr
end subroutine
end interface
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
double precision, allocatable, dimension(:, :) :: a
p => null()
print *, "a:", allocated(a)
print *, "p:", associated(p)
call hip_alloc(a)
print *, "a:", allocated(a)
print *, "p:", associated(p)
call hop
deallocate(a)
end program
subroutine hip_alloc(arr)
implicit none
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
double precision, allocatable, dimension(:, :), target :: arr
allocate(arr(100, 100))
arr(1, 1) = 3.1416d0
p => arr
end subroutine
subroutine hop
implicit none
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
print *, size(p, 1), size(p, 2), p(1, 1)
end subroutine
第三版,这里我们首先调用一个返回指针的函数,然后通过一个公共指针传递给一个子程序。该函数执行分配,如第二个示例所示。指针在主程序中被释放,但可能在其他地方。
program hip
implicit none
interface
function hip_alloc(n)
integer :: n
double precision, dimension(:, :), pointer :: hip_alloc
end function
end interface
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
p => null()
print *, "p:", associated(p)
p => hip_alloc(100)
print *, "p:", associated(p)
call hop
deallocate(p)
end program
function hip_alloc(n)
implicit none
integer :: n
double precision, dimension(:, :), pointer :: hip_alloc
allocate(hip_alloc(n, n))
hip_alloc(1, 1) = 3.1416d0
end function
subroutine hop
implicit none
double precision, dimension(:, :), pointer :: p
common /hiphop/ p
print *, size(p, 1), size(p, 2), p(1, 1)
end subroutine
答案 2 :(得分:0)
我不明白为什么写MODULE
不起作用,但您考虑过CONTAINS
吗? CONTAINS
下面的子程序可以看到CONTAINS
声明之上的所有内容:
PROGRAM call_both
INTEGER,DIMENSION(2) :: a, b
a = 1
b = 2
PRINT *,"main sees", a, b
CALL subA
CALL subB
CONTAINS
SUBROUTINE subA
PRINT *,"subA sees",a,b
END SUBROUTINE subA
SUBROUTINE subB
PRINT *,"subB sees",a,b
END SUBROUTINE subB
END PROGRAM call_both
输出为
main sees 1 1 2 2
subA sees 1 1 2 2
subB sees 1 1 2 2
这也适用于ALLOCATABLE
数组。