alex
alex

Reputation: 41

updating values of an array in a subroutine in fortran

i have the following module:

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

Now the subroutine "state system" uses the first subroutine "gradient". We start with an initial array "density" and the "state system" subroutine does an operation on each element of it, until we have a modified new array.
Now my problem is that I need to put that in a loop (let's say do j=1,10). So at each iteration of this loop, the subroutine (state of system and gradient)will return a modified array, then I want my program to replace the old array (that is an input for the two subroutines) with the new array obtained and do the execution again.
I can't figure out how to update those two arrays in the subroutines at each iteration. I tried defining a new array and putting all the new values in it, but It didn't lead anywhere.
If I want to do this, should I put the loop when calling the subroutine in the main program, or inside the subroutine?

Upvotes: 1

Views: 675

Answers (2)

AboAmmar
AboAmmar

Reputation: 5559

You should put the loop in the main program and each time you call the state_system subroutine, the density array gets updated and is fed again to the subroutine, etc.

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

Upvotes: 2

jack
jack

Reputation: 1790

I am not 100% sure to understand your question correctly but nonetheless the following code should do something along the lines of what your intent might be. Don't hesitate to give feedback if I misunderstood your question.

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

Upvotes: 0

Related Questions