我正在撰寫一個空氣動力學代碼(源代碼這里),使用良好的老Fortran。初始化的一部分是讀入一個檔案,其中包含表面網格的資訊,基本上是一組三角形或四邊形的面板組成的表面。我想用一個單一的panel型別來描述四邊形和三角形面板。為此,我寫了兩個初始化函式panel_init_3和panel_init_4,它們將根據面板的頂點數量將資料加載到該型別中。我想將這些系結到我的panel型別,并根據引數的數量來多載它們(即,如果它被傳遞一個整數和3個頂點物件,那么panel_init_3被呼叫,同樣地,4個頂點物件也被呼叫。
以下是該型別的源代碼:
module panel_mod
使用linked_list_mod
使用vertex_mod
隱式無
type panel
! 一個具有任意數量邊的面板
integer :: N ! 邊/頂點的數量
type(vertex_pointer),dimension(:),allocatable :: vertices
real,dimension(3) :: n_hat ! 法向量
real :: A ! 表面區域
包含
程序 :: init => panel_init_3, panel_init_4
程序 :: calc_area => panel_calc_area
程序 :: calc_normal => panel_calc_area
END 型別面板
包含
subroutine panel_init_3(this, v1, v2, v3)
! 初始化一個3層的面板
隱式無
class(panel),intent(inout) :: this
type(vertex),intent(in),target :: v1, v2, v3
! 設定邊的數量
this%N = 3
! 分配頂點陣列
allocate(this%vertices(this%N))
! 存盤資訊
this%vertices(1)%ptr => v1
this%vertices(2)%ptr => v2
this%vertices(3)%ptr => v3
! 計演算法向量
! 計算面積
結束subroutine panel_init_3
subroutine panel_init_4(this, v1, v2, v3, v4)
! 初始化一個有4個面的面板
隱式無
class(panel),intent(inout) :: this
type(vertex),intent(in),target :: v1, v2, v3, v4
! 設定邊的數量
this%N = 4
! 分配頂點陣列
allocate(this%vertices(this%N))
! 存盤資訊
this%vertices(1)%ptr => v1
this%vertices(2)%ptr => v2
this%vertices(3)%ptr => v3
this%vertices(4)%ptr => v4
! 計演算法向量
! 計算面積
結束subroutine panel_init_4
subroutine panel_calc_area(this)
隱式無
class(panel),intent(inout) :: this
結束子程式 panel_calc_area
子程式 panel_calc_normal(this)
隱式無
class(panel),intent(inout) :: this
結束子程式 panel_calc_normal
結束模塊 panel_mod
這個模塊的編譯很好。但是,當它被用在這里時
...
! 初始化三角形面板
如果(N == 3) 那么
call panels(i)%init(vertices(i1 1), vertices(i2 1), vertices(i3 1)) ! 需要 1,因為VTK是以0為索引的
! 初始化四邊形面板
否則
呼叫 panels(i)%init(vertices(i1 1), vertices(i2 1), vertices(i3 1), vertices(i4 1) )
結束 如果
...
我得到了編譯器的資訊
70 | call panels(i)%init(vertices(i1 1), vertices(i2 1), vertices(i3 1), vertices(i4 1))
| 1
錯誤。在程序呼叫中,(1)處的實際引數多于形式引數。
我是否超出了Fortran的能力,或者有什么方法可以做到這一點?我意識到我可以不通過系結和多載來實作這些,但我喜歡它的簡潔。我正在使用 gfortran 9.3.0.
。uj5u.com熱心網友回復:
在一個型別系結的程序宣告陳述句中,可以在一個串列中宣告多個系結名稱,因此我們可以有
type mytype
包含
程序 :: binding1, binding2
結束型別
給出了兩個系結的名稱。 這些是單獨的系結。 這些系結名稱決議為與每個名稱相同的程式。 也就是說,我們可以寫成
type mytype
包含
程序 :: binding1 => binding1, binding2 => binding2
結束型別
系結名稱的串列性質使
type mytype
包含
程序:: binding => binding1, binding2
結束型別
擁有串列binding=>binding1和binding2中的專案。這具有以下效果
像
type mytype
包含
程序 :: binding => binding1, binding2 => binding2
結束型別
也就是說,我們仍然有兩個不同的系結名稱,它們分別系結到一個程序。
我們沒有一個通用的binding系結名與特定的程序binding1和binding2。 為此,我們需要明確地創建一個通用的:
type mytype
包含
程序 :: binding1, binding2
generic :: binding => binding1, binding2
結束型別
在這個泛型陳述句中,串列中有binding1和binding2作為泛型binding的具體專案。 這些串列/陳述句的精確語法規則在Fortran 2018 7.5.5.
uj5u.com熱心網友回復:
這是可能的,但是你需要將init定義為一個通用程式(系結),其他兩個是特定的程式(系結)
包含
程序 :: panel_init_3
程序 :: panel_init_4
generic :: init => panel_init_3, panel_init_4
這與通常使用命名的interface塊的普通程序的做法非常相似,當你做
interface generic_init
存盤程序specific_init_3
存盤程序specific_init_4
結束介面
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313126.html
標籤:
