我试图为数值解算器制作灵活的用户界面。问题是我无法制定如何实现初始条件几何(矩形,球体等)的动态选择。我尝试将抽象类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的指针,但是不能将目标属性设置为派生类型字段。
答案 0 :(得分:1)
你所拥有的是非常接近工作,我认为你只是有一个误解。
但是这需要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
中的内容。
对每个构造函数使用sourced分配:
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
如果你有编译器支持多态变量的内部赋值(或使用定义的赋值)。