l3win
l3win

Reputation: 235

Link between variables in different programs in Fortran (f90)

I am trying to structure my Fortran program appropriately. I have a program GridGeneration.f90 that generates my grid mesh. I want to control the size of the grid in my main program, i.e. the grid size parameters N_x and N_y. Would this for example work?

module MySubsAndParameters

implicit none
integer :: N_x, N_y

include 'GridGeneration.f90'

code

end module MySubsAndParameters
program main

use MySubsAndParameters

N_x = 100
N_y = 50

code

end program main

How do N_x and N_y have to be defined in GridGeneration.f90 for this to be possible?

Also, are variable defined in GridGeneration.f90 now also defined and allocated in my module and main program? For example if there is a real x defined in GridGeneration.f90, can I use it in my main program?

Upvotes: 0

Views: 134

Answers (1)

Bálint Aradi
Bálint Aradi

Reputation: 3812

You question is somewhat unclear, but probably the following helps:

As for module variables: Every module variable can be accessed by all subroutines in that module and if it is not defined explicitely private it can be also accessed from the main program. So if you give them some value in the main program, the subroutines in the module will be aware of that. And vice versa, if you allocate them in some module procedure, the main program will be able to use them.

However, it is possible (and in my oppinion clearer), if you exchange the nr. of grid points and the grid via subroutine arguments (instead of module variables) between the main program and the subroutine. Consider the following (I assumed that your grid coordinates are integers):

module grid
  implicit none

contains

  subroutine gengrid(nx, ny, grid)
    integer, intent(in) :: nx, ny
    integer, intent(out) :: grid(:,:)

    ! create grid based on nx and ny

  end subroutine gengrid

end module grid


program test
  use grid
  implicit none

  integer, allocatable :: mygrid(:,:)
  integer :: nx, ny

  nx = 100
  ny = 50
  allocate(mygrid(nx, ny))
  call gengrid(nx, ny, mygrid)
  :

end program test
  • By passing the grid sizes explicitly to the routine, it can't happen to you, that you forget to initialize some module variables from outside before calling the routine. Also, it is immediately clear, which variables the routine needs to create the grid.

  • Actually you could even spare to pass the grid sizes to the subroutine, as it can guess it from the size of the allocated array:

    subroutine gengrid(grid)
      integer, intent(out) :: grid(:,:)
    
      integer :: nx, ny
    
      nx = size(grid, dim=1)
      ny = size(grid, dim=2)
      ! create grid based on nx and ny
    
    end subroutine gengrid
    
  • On the other hand, if you have a Fortran 2003 aware compiler, you can pass grid as an allocatable array to the gengrid routine and allocate it inside the routine. Although this is not possible in Fortran 90, all Fortran compilers I know implement allocatable arrays as subroutine arguments.

Upvotes: 1

Related Questions