I have two programs : 2D and 3D versions. For example, this is a simplified 2D version :
program main
integer, parameter :: nDim = 2
integer :: size
real, dimension(:,:,:), allocatable :: myArray
size=4 ! Normally read from a file
allocate(myArray(1:size,1:size,1:nDim))
call initArray(myArray)
contains
subroutine initArray(myArray)
real, dimension(1:size,1:size,1:nDim) :: myArray
myArray(1:size,1:size,1:nDim) = 5.d0
return
end subroutine initArray
end program main
And the 3D version,
program main
integer, parameter :: nDim = 3
integer :: size
real, dimension(:,:,:,:), allocatable :: myArray
size=4 ! Normally read from a file
allocate(myArray(1:size,1:size,1:size,1:nDim))
call initArray(myArray)
contains
subroutine initArray(myArray)
real, dimension(1:size,1:size,1:size,1:nDim) :: myArray
myArray(1:size,1:size,1:size,1:nDim) = 5.d0
return
end subroutine initArray
end program main
These programs are very similar and I would like to have only one program where the parameter nDim
determine everything.
But I have problem with the following statements and instructions :
- For
dimension
, I have not the same number of dimensions (3 or 4) - For
allocate
, the number of arguments is variable (3 or 4) - For initialisating
myArray
, the number of dimension is variable (3 or 4)
Is there a solution purely in fortran or should I use the C preprocessor ?
Thanks for answer.
This is a typical example where object-oriented programming helps. You have two programs that respond to the same API, but internal computations will be different (2D or 3D). You want to have 2d and 3d grids both extend a generic "grid type"
The actual implementation is up to you, but the key points are:
Expose all common "operations" (on a grid, for example) through the polymorphic API; define them in the
abstract
class, so the compiler will check that all you've done in the child classes is right;Hide all dimension-dependent code and data inside the derived types;
Ideally, you would try to define all routines of your public interface in a dimension-independent way. This is often not possible, in which case, you'll revert to use type-checking in those places where a shared call is not possible.
For example, you may need 2 or 3 input parameters to something: you can do
A simple test program will look like
Hope this helps, Federico