繁体   English   中英

fortran 2D阵列保存

[英]fortran 2D array save

我试图在每次运行后保存并重用一个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通过添加接入子程序来mymoduse -ing变量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 ,并且已知它总是具有相同的大小。

Ross解释了错误的来源,并提供了一些合理的其他方法。 下面是答案中未提及的另一个。 我不是说它更好,或者推荐它。

虽然自动对象不能具有save属性,但可以使用可分配的数组。 保存的本地可分配对象保留其分配状态,如果已分配,则保留其形状(如果是数组)和值。

real, allocatable, save :: dmsdust(:,:)  ! Initially not allocated
...
! Our first-time initialization and subsequent consistency check follows
if (.not.allocated(dmsdust)) then
  allocate(dmsdust(ngrid,99999), source=0.)
else
  if (size(dmsdust,1).ne.ngrid) error stop ! or some other handling
end if

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM