【问题标题】:Dynamic class in FortranFortran 中的动态类
【发布时间】:2020-02-17 02:41:33
【问题描述】:

在这个简单的程序中,当我编译程序时,它会给我一个关于“已分配的 BoundaryConditionLTU 已分配”的错误。我知道这个问题,但我不知道如何解决它。请让我知道如何解决这个问题。谢谢 此代码是我尝试用于边界条件的 CFD 代码的一部分。定义了三个一般边界条件(即 Dirichelet、Neumann 和混合 BC)。每个流动变量(例如速度、压力和温度)都将被分配代码开头提到的边界条件之一。 ClassBoundaryCond 是一个抽象类。注意:ClassDirichlet_BC、ClassNeumann_BC、ClassMix_B是ClassBoundaryCond(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

【问题讨论】:

  • 欢迎来到 SO!当您提出问题时,请尝试添加最少的内容:输入样本、预期输出样本、您尝试了什么、研究以及您在哪里堆叠。你尝试了什么?
  • 谢谢您,David Garcia:此代码是我尝试将 oop 用于边界条件的 CFD 代码的一部分。定义了三个一般边界条件(即 Dirichelet、Neumann 和混合 BC)。每个流动变量(例如速度、压力和温度)都将被分配代码开头提到的边界条件之一。我希望这会有所帮助。
  • 看起来您正在尝试独立分配 BoundaryConditionLTU 的每个元素并且类型不同。你cannot do this。如果这不是您想要做的,请稍微澄清您的问题。
  • 我看到的唯一allocate 语句是allocate(ClassDirichlet_BC::BoundaryConditionLTU(i)) 之类的语句。如果这些不是导致问题的行,那么请指出编译器抱怨的确切位置(如果您可以创建一个 minimal reproducible example 也会有所帮助,因为这里显示了很多代码,并且缺少一个公平的块)。
  • @PTRK,它不是,因为数组元素不是可分配对象。这是我之前提出的观点,并附有关于该主题的链接问题。

标签: arrays oop object dynamic fortran


【解决方案1】:

据我了解,class(ClassBoundaryCond),allocatable,Dimension(:) :: BoundaryConditionLTU 是 ClassBoundaryCond 扩展类型的对象的多态数组,这意味着您希望 BoundaryConditionLTU 是一个数组,其中一些元素是 ClassDirichlet_BC 类型,其他元素是 ClassNeumann_BC 等。 我认为这根本不可能,但我可能错了。

要实现这样一个对象,一种解决方案可能是(未测试):

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

【讨论】:

    猜你喜欢
    • 2015-05-05
    • 2014-10-05
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 2019-04-24
    • 2012-01-27
    相关资源
    最近更新 更多