- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I want to allocate an allocatable array of abstract class objects in a subroutine.
Subroutine adds a new object to the existing array of abstract objects by resizing the array:
subroutine apmArrayAddNewMember(array, member) use class_absMaterial !! abstract class use class_mat02 !! child class implicit none ! class mat02 extends abstract class absMaterial class(absMaterial), allocatable, dimension(:), & intent(inout) :: array !! existing array type(mat02), target, intent(in) :: member !! new object class(absMaterial), allocatable, dimension(:) :: temp integer intSize type(mat02), pointer, dimension(:) :: molder if (allocated(array)) then intSize = size(array) allocate(molder(intSize+1)) allocate(temp, mold=molder) deallocate(molder) temp(1:intSize) = array temp(intSize+1) = member deallocate(array) call move_alloc(temp, array) else allocate(molder(1)) allocate(array(1), mold=molder) deallocate(molder) array(1) = member end if end subroutine apmArrayAddNewMember
I am not sure if this works correctly. As you can see I have to allocate molder so that I can specify 'mold ='
I could not find any other way, also I don't know what if all the objects are not mat02 class and be another objects that extends absMaterial.
Will this code steel works if the other objects need same or less memory as mat02?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arrays in Fortran are all contiguous with all elements the same size. Therefore you can only have one concrete type for the whole array.
The usual way around this is to create a concrete type like this:
type MaterialHolder class(absMaterial), allocatable :: item end type type(MaterialHolder), allocatable :: array(:)
Now you can allocate the array without using a mold, then allocate each item to any non-abstract child class of absMaterial:
allocate(mat02::array(1)%item) allocate(mat03::array(2)%item)
While you are re-sizing you can use move_alloc on each item.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Andrew Smith wrote:
Arrays in Fortran are all contiguous with all elements the same size. Therefore you can only have one concrete type for the whole array.
The usual way around this is to create a concrete type like this:
type MaterialHolder class(absMaterial), allocatable :: item end type type(MaterialHolder), allocatable :: array(:)Now you can allocate the array without using a mold, then allocate each item to any non-abstract child class of absMaterial:
allocate(mat02::array(1)%item) allocate(mat03::array(2)%item)While you are re-sizing you can use move_alloc on each item.
Dear Andrew, Thank for your reply.
I wish it was possible to use dimension() statement inside allocate!
allocate(type(mat02), dimension(intSize) :: array)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
S. MPay wrote:
..
I wish it was possible to use dimension() statement inside allocate!
allocate(type(mat02), dimension(intSize) :: array)
@S. MPay,
Note you can do
allocate( mat02 :: array(intSize) )
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Question: As I execute this Program will give a compilation error such as BoundaryConditionLTu is allocated before. Iknow the problem but I don't know how to fix it. Please let me know how to use Dynamic class in this simple program.
Thank you
:
:
! ClassBoundaryCond is an abstract class
class(ClassBoundaryCond),allocatable,Dimension(:) :: BoundaryConditionLTU
subroutine initiateBoundaryCondition()
implicit none
integer :: i
! Date : 06/24/2019
! Arguments
! Body
do i=1,6
if (leftBC(i) == 0) then
allocate(ClassDirichlet_BC::BoundaryConditionLTU(i))
else if (leftBC(i) == 1) then
allocate(ClassNeumann_BC::BoundaryConditionLTU(i))
else if (leftBC(i) == 2) then
allocate(ClassMix_BC::BoundaryConditionLTU(i))
end if
end do
end subroutine initiateBoundaryCondition

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