我正在尝试为数值求解器制作灵活的用户界面。问题是,如何实现初值几何(矩形、球面等)的动态选择,是一个很难解决的问题。我尝试使用抽象类initial_conditions_geometry作为父类,其子类rectangular和sphere指定了某些属性,并为几何学实现了方法in_bounds:
type ,abstract :: initial_conditions_geometry
contains
procedure (in_bounds) ,deferred :: in_bounds
end type
abstract interface
logical function in_bounds(this,coordinates)
import :: rkind
import :: initial_conditions_geometry
class(initial_conditions_geometry) ,intent(in) :: this
real(rkind) ,dimension (:) ,intent(in) :: coordinates
end function in_bounds
end interface
type ,extends(initial_conditions_geometry) :: rectangular
integer ,dimension(:,:) ,allocatable :: rectangular_bounds
contains
procedure :: in_bounds => in_bounds_rectangular
end type
type ,extends(initial_conditions_geometry) :: sphere
integer ,dimension(:,:) ,allocatable :: sphere_bounds
integer ,dimension(:) ,allocatable :: sphere_center
contains
procedure :: in_bounds => in_bounds_sphere
end type
interface rectangular
procedure constructor_rectangular
end interface
interface sphere
procedure constructor_sphere
end interface下面是initial_conditions_layer类定义,它包含初始条件几何和分布:
type :: initial_conditions_layer
class(initial_conditions_geometry) ,allocatable :: layer_geometry
type(initial_conditions_distribution) :: distributor
end type
interface initial_conditions_layer
procedure constructor
end interface问题是:如何为initial_conditions_layer动态创建构造器(取决于某些文本文件中的几何类型)设置layer_geometry类型(矩形、球形等)?
编辑,也许添加一些解决这个问题的尝试是有用的。我尝试按照以下方式组织initial_conditions_layer对象的构造函数:
type(initial_conditions_layer) function constructor(dimensions,layer_number,initial_conditions_data_file_unit)
integer ,intent(in) :: layer_number
integer ,intent(in) :: initial_conditions_data_file_unit
integer ,intent(in) :: dimensions
character(len=20) :: layer_distribution_type
character(len=20) :: layer_geometry_name
call get_layer_properties(initial_conditions_data_file_unit,layer_number,layer_geometry_name,layer_distribution_type)
select case(layer_geometry_name)
case('rectangular')
allocate(rectangular::constructor%layer_geometry)
case('sphere')
allocate(sphere::constructor%layer_geometry)
end select
select type(constructor%layer_geometry)
type is(rectangular)
constructor%layer_geometry = rectangular()
type is(sphere)
constructor%layer_geometry = sphere()
end select
end function但这需要在select类型构造中使用associate_name。Associate_name应该是指向initial_conditions_geometry的指针,但不能将目标属性设置为派生类型字段。
发布于 2015-01-28 18:55:43
你所拥有的与工作相当接近,我认为你只是有一个误会。
但这需要在select类型构造中使用associate_name。Associate_name应该是指向initial_conditions_geometry的指针,但不能将目标属性设置为派生类型字段。
在这种情况下需要一个associate-name,但是,不管=>语法如何,都不涉及指针。这样你就可以在没有其他变化的情况下
select type(clg => constructor%layer_geometry)
type is(rectangular)
clg = rectangular()
type is(sphere)
clg = sphere()
end select或者,在这种简单的情况下,可以完全取消select type构造,并处理您已经拥有的select case中的内容。
在每个构造函数中使用源分配:
select case(layer_geometry_name)
case('rectangular')
allocate(constructor%layer_geometry, source=rectangular())
case('sphere')
allocate(constructor%layer_geometry, source=sphere())
end select甚至
select case(layer_geometry_name)
case('rectangular')
constructor%layer_geometry = rectangular()
case('sphere')
constructor%layer_geometry = sphere()
end select如果编译器支持对多态变量的内部赋值(或通过使用定义的赋值)。
https://stackoverflow.com/questions/28195626
复制相似问题