This question follow this one(fortran, how to have a number of variable dimensions in dimension (allocatable) , allocate and affectation?).
Frederico suggested me to use OOP and gave me a solution to my initial problem. Now, I would like to use submodule (cf 4. The advantages of submodules in https://fortran.bcs.org/2004/ukfortran04.htm).
This is my code :
module grids
implicit none
type, abstract, public :: grid
contains
procedure (grid_init), deferred :: init
end type grid
type, public, extends(grid) :: grid2D
real, dimension(:,:), allocatable :: myArray
contains
procedure :: init=>grid_init
end type grid2D
type, public, extends(grid) :: grid3D
real, dimension(:,:,:), allocatable :: myArray
contains
procedure :: init=>grid_init
end type grid3D
! Define procedure APIs
abstract interface
module subroutine grid_init(this,size)
class(grid), intent(inout) :: this
integer, intent(in) :: size
end subroutine grid_init
end interface
end module grids
submodule (grids) grid2D
contains
module procedure grid_init
allocate(this%myArray(size,size))
end subroutine grid_init
end submodule grid2D
submodule (grids) grid3D
contains
module procedure grid_init
allocate(this%myArray(size,size,size))
end subroutine grid_init
end submodule grid3D
program main
use grids
type(grid2D) :: myGrid
call myGrid%init(3)
print *,myGrid%myArray
end program main
But, it does not compile because grid_init
is an abstract interface
. What must I change in this code ?
edit 1
Federico said in his answer : To put in a submodule only the routines, without the type definition, you may have to define additional interfaces for all their functions, which is nonsense. I understand clearly the problem. This part of code illustrates well the problem (For sake of brevity, module grids_base
is omitted but it is unchanged and the same modifications applied to grids_3d)
module grids_2d
use grids_base
implicit none
type, public, extends(grid) :: grid2D
real, dimension(:,:), allocatable :: myArray
contains
procedure :: init=>grid_init2d
end type grid2D
interface
module subroutine grid_init2d(this,size)
class(grid2D), intent(out) :: this
integer, intent(in) :: size
end subroutine grid_init2d
end interface
end module grids_2d
submodule (grids_2d) grid_2dsub
contains
module procedure grid_init2d
allocate(this%myArray(size,size))
end procedure grid_init2d
end submodule grid_2dsub
I wonder, if it is possible (with some "OOP tricks", that I am not aware of) to simplify this code because grid_init2d
interface is very similar to the grid_init
abstract interface. The only difference is the class
of this
: grid
changes togrid2D
but the type grid2D
is derived from grid
where the abstract interface grid_init
is defined.