- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In our software i am using quite a lot of allocatable arrays which i have to "reallocate" to runtime for increasing or decreasing. (static arrays are not an option :) )
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
module reallocate
interface realloc
module procedure realloc_int1d
module procedure realloc_real1d
...
end interface realloc
contains
subroutine realloc_int1d( array, newsize )
integer, dimension(:), allocatable:: array
include "actual_realloc_code.f90"
endsubroutine
subroutine realloc_real1d( array, newsize )
real, dimension(:), allocatable :: array
include "actual_realloc_code.f90"
endsubroutine
...
end module
Via the INCLUDE statement you canrepeat the boilerplate code.
With derived types you can even put the declarations in such an
INCLUDE file, but I do not have the time at the moment to elaborate
on that.
Note that F2003's move_alloc routine makes life very much simpler.
(No more copying needed)
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But i do have to write all subroutines for special types and bind them to the interface, which is quite the main "problem" i have.
Not that i am not know what i am doing hehe...but life would be SO much easier by using only 1 simple subroutine for all cases.
never heard about that but sounds interessing....think i cant use it actually if the whole software is written in F90 can i? (fortran compiler 11 by the way)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
newsize = oldsize + increment
allocate (temp(newsize), stat=ierr)
if (ierr == 0) then
temp(1:oldsize) = array
call move_alloc(temp, array)
oldsize = newsize
endif
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If your version of the compiler supports the /assume:realloc_lhs flag, reallocating an array of any type can be done during the assignment, say:
[fortran]implicit none real, allocatable :: a(:) allocate (a(1:0)) !empty array print *, "0 entries:", a a = [a, 1.] !increase size print *, "1 entry:", a a = [a, 2., 3., 4.] !increase size print *, "4 entries:", a a(:) = [1., 2., 3., 5.] !no reallocation print *, "4 entries:", a a = a(:3) !decrease size print *, "3 entries:", a a = a(:0) !make empty print *, "0 entries:", a end [/fortran]
With /assume:realloc_lhs, you'll have to use (:) for the cases when you want to avoid reallocation, as shown in the example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Especially cause F90 is not object orientated...for what i read about it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
F90's transfer intrinsic can be used to "type cast" the value of a variable of arbitrary type to a value of another type. The programmer needs to ensure that the "another type" (which can be an array) is large enough to accomodate the size in memory of the original variable, or you will not be able to reverse the type cast. Typically a 1D array of integers is used (perhaps an 1D array of INTEGER(1) under ifort) - so your typecastedArray would need to be a 2D array.
Fortran 2003 introduces a number of other possibilities (CLASS(*) may help), but if you have limited yourself to F90 (seriously??? Its pretty hard to justify that sort of restriction today) then obviously you will be missing out F2003's "cool features".
(Note that allocatable arguments, allocatable function results and allocatable derived type components are all not available in F90.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem is that you keep mentioning "reallocation", and for that you can rely on reallocating the array during assignment (which I showed in my previous post), which is a Fortran 2003 feature. Because it's part of the language, it works the same regardless of whether you have an array of intrinsic (logical, integer, real, character) or derived type.
Even though you mentioned that you're restricting yourself to F90, it seems to be a relative restriction for you ---since the ALLOCATABLE attribute for function/subroutine arguments is a Fortran 2003 feature.
Other than the TRANSFER intrinsic, there is no typecasting in Fortran. As IanH suggested, you could use CLASS(*) combined with type-guards (yet another Fortran 2003 feature), but besides being more complex than reallocate on assignment, it's not yet supported by Intel Fortran ---i.e., the CLASS(*) feature still doesn't work well with arrays.
The following should, in theory, be close to what you want (although the code doesn't even compile, so it might not be valid):
[fortran]program test implicit none integer, allocatable :: a(:) character(5), allocatable :: b(:) allocate (a(1), b(2)) a = 1 b = 'two' print *, 'a, before:',a call reallocate(a, [2, 2]) print *, 'a, after:',a print *, 'b, before:',b call reallocate(b, [character(5) :: 'three', 'three', 'three']) print *, 'b, after:',b contains subroutine reallocate (array, increment) class(*), allocatable, intent(INOUT) :: array(:) class(*), intent(IN) :: increment(:) integer, allocatable :: auxi(:) character(5), allocatable :: auxc(:) select type (array) type is (integer) select type (increment) type is (integer) call MOVE_ALLOC(array, auxi) allocate (integer :: array(SIZE(auxi) + SIZE(increment))) array(:SIZE(auxi)) = auxi array(SIZE(auxi)+1:) = increment class default stop 'type not supported' end select type is (character(*)) select type (increment) type is (character(*)) call MOVE_ALLOC(array, auxc) allocate (character(5) :: array(SIZE(auxc) + SIZE(increment))) array(:SIZE(auxc)) = auxc array(SIZE(auxc)+1:) = increment class default stop 'type not supported' end selectclass default stop 'type not supported' end select end subroutine end program test[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using the Fortran Preprocessor, you might be able to reduce this to 1 or 2 lines.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page