2

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 This code is part of CFD code that I'm trying to use for Boundary conditions. Three general boundary conditions are defined (i.e Dirichelet, Neumann, And mixed BC). Each of flow variables such as velocity, pressure, and temperature will be assigned one of the mentioned boundary conditions at the beginning of the code. ClassBoundaryCond is an abstract class. Note: ClassDirichlet_BC, ClassNeumann_BC, and ClassMix_B are the inheirtance of the ClassBoundaryCond (Extended type of the ClassBoundaryCond).

    module BoundaryCondition
    ! Date : 08/1/2019
    use Varibales_Nst_NoImm_2D_MPH_DEM
    !use SubroutineModule
    implicit none
    !=====================================================================
    ! Classes
    type,abstract :: ClassBoundaryCond
       contains
       procedure(InterfaceBound)  ,deferred :: evaluateBound
       procedure(InterfaceBound_N),deferred :: evaluateBound_Neu
    end type ClassBoundaryCond
!............................................    
    type,extends(ClassBoundaryCond) :: ClassDirichlet_BC
    contains
    procedure :: evaluateBound=>evaluateDir
    procedure :: evaluateBound_Neu=>evaluateNeu_Dir
    end type ClassDirichlet_BC
    !==============
    type,extends(ClassBoundaryCond) :: ClassNeumann_BC
    contains
    procedure :: evaluateBound=>evaluateNeu
    procedure :: evaluateBound_Neu=>evaluateNeu_Neu
    end type ClassNeumann_BC
    !==============
    type,extends(ClassBoundaryCond) :: ClassMix_BC
    contains
    procedure :: evaluateBound=>evaluateMix
    procedure :: evaluateBound_Neu=>evaluateNeu_Mix
    end type ClassMix_BC
    !==============
    !=====================================================================
    ! Interfaces
    !---------------------------------------
    abstract interface
    !---------------------------------------
    subroutine InterfaceBound(this)
    import :: ClassBoundaryCond
    class(ClassBoundaryCond) :: this
    end subroutine InterfaceBound
    !---------------------------------------
    end interface
    !=====================================================================
    ! ClassBoundaryCond is an abstract class
    !=====================================================================
    ! Decelerations
    class(ClassBoundaryCond),allocatable,Dimension(:) :: BoundaryConditionLTU
    !=====================================================================
    contains
    !=====================================================================

    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
    SUBROUTINE evaluateDir(this)
    Implicit None
    !     Start of Variable Definition
    !     ----------------------------
    Class(ClassDirichlet_BC) :: this
    END SUBROUTINE
    SUBROUTINE evaluateNeu(this)
    Implicit None
    !     Start of Variable Definition
    !     ----------------------------
    Class(ClassNeumann_BC) :: this


    END SUBROUTINE
    SUBROUTINE evaluateMix(this)
    Implicit None
    !     Start of Variable Definition
    !     ----------------------------
    Class(ClassMix_BC) :: this


    END SUBROUTINE
    end module BoundaryCondition
albert
  • 8,285
  • 3
  • 19
  • 32
David
  • 21
  • 2
  • Welcome to SO! When you place a question try to add a minimum content: input sample, expected output sample, what did you try, research and where are you stacked. What did you try? – David García Bodego Oct 21 '19 at 03:06
  • Thank you, David Garcia: This code is part of CFD code that I'm trying to use oop for Boundary conditions. Three general boundary conditions are defined (i.e Dirichelet, Neumann, And mixed BC). Each of flow variables such as velocity, pressure, and temperature will be assigned one of the mentioned boundary conditions at the beginning of the code. I hope this will help. – David Oct 21 '19 at 03:27
  • So please, add this information to your post and show us what did you try... – David García Bodego Oct 21 '19 at 03:28
  • 1
    It looks like you are trying to allocate each element of `BoundaryConditionLTU` independently and of varying type. You [cannot do this](https://stackoverflow.com/q/33621185/3157076). If that's not what you are wanting to do, then please clarify your question a little. – francescalus Oct 21 '19 at 08:59
  • Actually I am trying to declare BoundaryConditionLTU as an allocatable array, then allocating a class such as ClassDirichlet_BC or ClassNeumann_BC with BoundaryConditionLTU. This will help to set a different boundary condition outside the iteration loop. The problem is BoundaryConditionLTU allocated more than once. I do not know how to write the subroutine initiateBoundaryCondition to avoid this. – David Oct 21 '19 at 09:19
  • 1
    The only `allocate` statements I see are those like `allocate(ClassDirichlet_BC::BoundaryConditionLTU(i))`. If those aren't the lines causing the problem then please point to the exact location where the compiler is complaining (it'll also help if you could create a [mre] as there's a lot of code shown here, and a fair chunk missing). – francescalus Oct 21 '19 at 09:28
  • Is `allocate(ClassDirichlet_BC::BoundaryConditionLTU(i))` a valid fortran statement at all ? – PTRK Oct 22 '19 at 07:48
  • 1
    @PTRK, it isn't, because an array element is not an allocatable object. This is the point I made earlier, with a linked question on the topic. – francescalus Oct 22 '19 at 08:28

1 Answers1

1

From what I understand class(ClassBoundaryCond),allocatable,Dimension(:) :: BoundaryConditionLTU is a polymorphic array of object of extended type of ClassBoundaryCond, meaning you want BoundaryConditionLTU to be an array where some elements are ClassDirichlet_BC type, other ClassNeumann_BC, etc. I don't think it's possible at all, but I may be wrong.

To implement such an object, one solution could be (not tested):

module BoundaryCondition
! ... some codes

! We define a derived type where it's bc component can be any extended type of ClassBoundaryCond
type :: polymorphic_array_type
  class(ClassBoundaryCond),allocatable :: bc
end type

! Then we declare a dynamic array of this type
type(polymorphic_array_type),dimension(:), allocatable :: BoundaryConditionLTU

! ... some codes

!=====================================================================
contains
!=====================================================================

subroutine initiateBoundaryCondition()
implicit none

! We have i from 1 to 6 so somewhere there is a statement
! allocate(BoundaryConditionLTU(6))

do i=1,6
    if (leftBC(i) == 0) then
        allocate(BoundaryConditionLTU(i)%bc,source=ClassDirichlet_BC())
    else if (leftBC(i) == 1) then
        allocate(BoundaryConditionLTU(i)%bc,source=ClassNeumann_BC())
    else if (leftBC(i) == 2) then
        allocate(BoundaryConditionLTU(i)%bc,source=ClassMix_BC())
    end if
end do

! Then you may use BoundaryConditionLTU(i)%bc
! ... some codes
PTRK
  • 899
  • 1
  • 5
  • 18