Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays fortran 2D数组保存_Arrays_Fortran_Fortran90_Allocation - Fatal编程技术网

Arrays fortran 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)::

我试图在每次运行后保存和重用一个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
每次执行
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