Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Dynamic Class

Lee__Ho
Beginner
370 Views

In this simple program, when I compile the program it will give me an error in regard to "the allocated BoundaryConditionLTU is already allocated". I know the problem but I don't know how to fix it. Please let me know how to fix this. Thank you

 

    :
    :
    ! ClassBoundaryCond is an abstract class. Note: ClassDirichlet_BC, ClassNeumann_BC, and ClassMix_B are the inheirtance of the ClassBoundaryCond (Extended type of the ClassBoundaryCond).
    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
 

0 Kudos
2 Replies
Lee__Ho
Beginner
370 Views
Note ClassDirichlet_BC, ClassNeumann_BC, and ClassMix_BC are exended type of ClassBoundaryCond. Actually they are the inheritance of ClassBoundaryCond.
0 Kudos
Ferdinand_T_
New Contributor II
370 Views

It appears you intend to populate an array "BoundaryConditionLTU" with boundary conditions of different dynamic types, depending on the input "leftBC".

There are two problems in your code:
(1) An array can only be allocated once and as a whole (array elements cannot be allocated individually)
(2) All array elements must be of equal type (one cannot mix different dynamic types in a single array)

The standard solution is to create a container type, e.g.

type :: ClassBoundaryCondContainer
    class(ClassBoundaryCond), allocatable :: bc
end type

and then to work with an array of containers instead:

type(ClassBoundaryCondContainer), dimension(:), allocatable :: BoundaryConditionLTU

Now these containers can be individually allocated and accessed via BoundaryConditionLTU(i)%bc, and your code would only need to change minimally:

! Make room for 6 BC's
allocate(BoundaryConditionLTU(6))

! Allocate individual BC's depending on leftBC
do i=1,6
    if (leftBC(i) == 0) then
        allocate(ClassDirichlet_BC::BoundaryConditionLTU(i)%bc)
    else if (leftBC(i) == 1) then
        allocate(ClassNeumann_BC::BoundaryConditionLTU(i)%bc)
    else if (leftBC(i) == 2) then
        allocate(ClassMix_BC::BoundaryConditionLTU(i)%bc)
    end if
end do

I hope that was useful?
Kind Regards, Ferdinand

0 Kudos
Reply