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
ビギナー
710件の閲覧回数

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 件の賞賛
2 返答(返信)
Lee__Ho
ビギナー
710件の閲覧回数
Note ClassDirichlet_BC, ClassNeumann_BC, and ClassMix_BC are exended type of ClassBoundaryCond. Actually they are the inheritance of ClassBoundaryCond.
Ferdinand_T_
新規コントリビューター II
710件の閲覧回数

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

返信