Arrays fortran 2D数组保存
我试图在每次运行后保存和重用一个2D变量,但我遇到了一些错误,如自动对象无法保存等。 下面是子程序:Arrays fortran 2D数组保存,arrays,fortran,fortran90,allocation,Arrays,Fortran,Fortran90,Allocation,我试图在每次运行后保存和重用一个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)::
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
每次执行dust\u sum\u test
时都会“自动”形成dmsdust
,其大小基于dmsdust
的输入。因此,dmsdust
是一个自动数组。
子例程dust\u sum\u test
每次运行时都会接受ngrid
的值,但不能保证ngrid
每次都是相同的。如果它第一次运行时ngrid
为1,第二次运行时ngrid
为2,该怎么办?如何保存dmsdast
并改变形状?所以编译器不会让你犯这个错误
解决问题的真正办法是改变你的方法。您的问题没有说明为什么需要存储dust
的历史记录,但我假设您需要。但是,您没有理由将其存储在此子例程中!事实上,将其存储在子例程中(作为save
d值)意味着很难访问它。相反,我认为还有两个好的选择
使用模块
模块是现代fortran的主要功能,可以存储数据和子例程。您可以在此模块中保留灰尘的历史记录,并在模块内外访问它。实现将类似于:
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
在这个实现中,您必须在开始时调用initdmsust
一次来分配存储空间。然后在以后每次调用dmsdust
时使用它。您可以通过将访问子例程添加到mymod
或use
来访问dmsdust
——从代码的另一部分调用变量dmsdust
将历史记录存储在调用例程中
此解决方案更简单,但不具有可扩展性或优雅性。不要让dust\u sum\u test
负责保持dmsdust
,而是让负责调用dust\u sum\u 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
,并且已知其大小始终相同。错误的来源,并提供一些合理的其他方法。下面是另一个答案中未提及的问题。不过,我不是说它更好,也不是推荐它
虽然自动对象不能具有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