As you suggest that the answer to another question, looking at ragged arrays may be what you want, I'll briefly mention a usability extension to that answer (hinted at in comment by Doug Lipinski).
For a base type, representing the variable-length dimension, given by High Performance Mark
type :: vector
integer, dimension(:), allocatable :: elements
end type vector
and a type for an array of those
type :: ragged_array
type(vector), dimension(:), allocatable :: vectors
end type ragged_array
one has the allocation steps
type(ragged_array) :: ragarr
allocate(ragarr%vectors(5))
allocate(ragarr%vectors(1)%elements(3))
! etc.
[Alternatively, one may be tempted to just have an array of type(vector)
.]
For the usability aspect one could create a structure constructor which does the numerous allocations, or even rely on automatic allocation for the variable length components.
In the latter case, which makes sense if the values, not just the extents, are known at creation.
allocate(ragarr%vectors(5))
ragarr%vectors(1)%elements = [1, 6, 13]
! etc.
For the former case, something like
module ragged
implicit none
type :: vector
integer, dimension(:), allocatable :: elements
end type vector
type :: ragged_array
type(vector), dimension(:), allocatable :: vectors
end type ragged_array
interface ragged_array
module procedure ragged_constructor
end interface ragged_array
contains
function ragged_constructor(sizes) result(ra)
integer, intent(in) :: sizes(:)
type(ragged_array) ra
integer i
allocate(ra%vectors(SIZE(sizes)))
do i=1,SIZE(sizes)
allocate(ra%vectors(i)%elements(sizes(i)))
end do
end function ragged_constructor
end module ragged
program test
use ragged
implicit none
type(ragged_array) :: ra
ra = ragged_array([3,4,6,1,12])
end program