我试图在每次运行后保存并重用2D变量,但出现一些错误,例如无法保存自动对象等。
这是子例程:
subroutine dust_sum_test(ngrid,count,dust_in,dust_out)
!Subroutine to accumulate and release dust in timely manner
implicit none
integer,intent(in)::ngrid
integer,intent(in)::count
real,intent(in)::dust_in(ngrid)
real,intent(out)::dust_out(ngrid)
real,save::dmsdust(ngrid,99999) ! dummy local variable
integer::i
if (count.gt.1) then
dmsdust(:,count)=dmsdust(:,count-1)+dust_in
dust_out=dmsdust(:,count)
else
dust_out=dust_in
dmsdust(:,count)=0.0
endif
write(*,*)'The current count is = ', count
end subroutine dust_sum_test
我需要将当前值与以前的dmsdust值相加。请让我知道如何解决此问题。
最佳答案
错误是正确的-您无法保存自动数组。此特定错误的原因是:
每次dmsdust
执行时,都会自动根据dust_sum_test
的输入大小自动形成dmsdust
。所以dmsdust
是一个自动数组。
子例程dust_sum_test
每次运行时都使用ngrid
的值,但是没有保证ngrid
每次都相同。如果第一次运行ngrid
为1,第二次ngrid
为2怎么办? dmsdust
如何保存并改变形状?因此,编译器不会让您犯此错误。
解决问题的真正方法是改变您的方法。您的问题并没有说明为什么需要存储dust
的历史记录,但是我想您需要这样做。但是,没有理由将其存储在此子例程中!实际上,将其存储在子例程中(作为save
d值)意味着将很难访问它。相反,我相信还有另外两个不错的选择。
使用模块
模块是现代fortran的基本组成部分,可以存储数据和子例程。您可以将dust
的历史记录保留在此模块中,并在模块内外访问它。该实现将类似于:
module mymod
implicit none
real, allocatable :: dmsdust(:,:)
contains
subroutine init_dmsdust(ngrid)
integer, intent(IN) :: ngrid
allocate(dmsdust(ngrid,9999))
end subroutine init_dmsdust
subroutine dust_sum_test(ngrid,count,dust_in,dust_out)
! -- all your other code, but now dmsdust is not an automatic array
end subroutine dust_sum_test
end module mymod
在此实现中,必须在开始时一次调用
init_dmsdust
来分配存储空间。然后,稍后在每次调用dmsdust
时使用它。您可以通过将访问子例程添加到dmsdust
或mymod
-在代码的另一部分中使用变量use
来访问dmsdust
。将历史记录存储在调用例程中
该解决方案更简单,但不那么可扩展或优雅。不要给
dust_sum_test
保留dmsdust
的工作,而是让负责调用dust_sum_test
的例程例程分配并传递dmsdust
。您的调用例程的一部分如下所示:allocate(dmsdust(ngrid,9999))
do count=1,max ! -- The main loop
call dust_sum_test(ngrid,count,dust_in,dust_out,dmsdust)
! some other stuff
enddo
然后子例程看起来像:
subroutine dust_sum_test(ngrid,count,dust_in,dust_out,dmsdust)
implicit none
real, intent(INOUT) :: dmsdust(:,:)
! -- All the other stuff
end subroutine dust_sum_test
这样,调用例程便可以访问
dmsdust
,并且始终具有相同的大小。