Reputation: 235
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
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