在 Fortran 的子程序中更新数组的值

updating values of an array in a subroutine in fortran

我有以下模块:

module prestel
implicit none
contains
  subroutine gradient(rho,N,gradiant_rho)
    implicit none
    real(kind=real), allocatable  :: rho(:) 
    real(kind=real),allocatable   :: gradiant_rho(:)
    integer,intent(in)          :: N
    integer                     :: i
    do i = 1,N
      gradiant_rho(i) = rho(i) - 2
    end do
  end subroutine gradient

  subroutine state_system(density,N,grad_density)

  implicit none
  real(kind=real), allocatable :: density(:)
  real(kind=real), allocatable :: grad_density(:)
  integer :: i,j
  integer, intent(in) :: N
    call gradient(density,velocity,N,grad_density,grad_velocity)
    do i=1,N
      density (i+1) = density(i) - 2*grad_density(i))
    end do
end subroutine state_system
end module prestel

现在子程序“状态系统”使用第一个子程序“梯度”。我们从一个初始数组“density”开始,“state system”子程序对它的每个元素进行操作,直到我们有一个修改过的新数组。
现在我的问题是我需要将其放入循环中(假设 j=1,10)。所以在这个循环的每次迭代中,子程序(系统状态和梯度)将 return 一个修改后的数组,然后我希望我的程序用新的替换旧数组(这是两个子程序的输入)得到数组再执行一次。
我不知道如何在每次迭代时更新子例程中的这两个数组。我尝试定义一个新数组并将所有新值放入其中,但它并没有引导到任何地方。
如果我要这样做,调用子程序时的循环应该放在主程序中,还是放在子程序中?

我不是 100% 肯定能正确理解您的问题,但是下面的代码应该按照您的意图做一些事情。 如果我误解了您的问题,请随时提供反馈。

module prestel_m
  implicit none

  private
  public state_system

contains

  subroutine gradient(density, gradiant_density)
    real, intent(in)  :: density(:)
    real, intent(out) :: gradiant_density(:)

    gradiant_density = density - 2
  end subroutine gradient

  subroutine state_system(density)
    real, intent(inout) :: density(:)

    integer           :: j
    real, allocatable :: grad_density(:)

    allocate (grad_density(size(density)))

    do j = 1, 10
      call gradient(density, grad_density)

      density = density - 2*grad_density
    end do
  end subroutine

end module

您应该将循环放在主程序中,每次调用 state_system 子例程时,density 数组都会更新并再次提供给子例程等。

module prestel_m
  implicit none
  private
  public state_system

contains

  subroutine gradient(density, gradiant_density)
    real, intent(in) :: density(:)
    real, intent(out) :: gradiant_density(:)    
    gradiant_density = density - 2  
  end subroutine gradient

  subroutine state_system(density)
    real, intent(inout) :: density(:)
    real, allocatable :: grad_density(:)

    allocate (grad_density(size(density)))

    call gradient(density, grad_density)
    density = density - 2*grad_density
  end subroutine

end module


program test_state_system
  use prestel_m          
  integer, parameter :: n = 5 ! just for this example
  real, allocatable :: density(:)
  integer :: j
  
  allocate (density(n))
  call random_number(density) ! just for this example

  do j = 1, 10
    ! here, you get updated version of 'density' for each iteration
    call state_system(density)
  end do

end program