2013-05-10 97 views
5

我對Fortran很新,爲了研究我需要運行一個模型的怪物,所以我正在學習,因爲我正在學習。所以如果我問一個「愚蠢」的問題,我很抱歉。 我試圖編譯(Mac OSX,從命令行),我已經設法解決了一些事情,但現在我遇到了一些我不知道如何解決的問題。我想我明白了這個錯誤背後的想法,但是,不知道如何解決。Fortran - 顯式接口

該模型是巨大的,所以我只會發布我認爲相關的代碼段(雖然我可能是錯的)。我有幾個子程序文件,啓動用:

!==========================================================================================! 
! This subroutine simply updates the budget variables.         ! 
!------------------------------------------------------------------------------------------! 
subroutine update_budget(csite,lsl,ipaa,ipaz) 

    use ed_state_vars, only : sitetype  ! ! structure 
    implicit none 

    !----- Arguments -----------------------------------------------------------------------! 
    type(sitetype) , target  :: csite 
    integer   , intent(in) :: lsl 
    integer   , intent(in) :: ipaa 
    integer   , intent(in) :: ipaz 
    !----- Local variables. ----------------------------------------------------------------! 
    integer      :: ipa 
    !----- External functions. -------------------------------------------------------------! 
    real   , external :: compute_water_storage 
    real   , external :: compute_energy_storage 
    real   , external :: compute_co2_storage 
    !---------------------------------------------------------------------------------------! 


    do ipa=ipaa,ipaz 
     !------------------------------------------------------------------------------------! 
     !  Computing the storage terms for CO2, energy, and water budgets.    ! 
     !------------------------------------------------------------------------------------! 
     csite%co2budget_initialstorage(ipa) = compute_co2_storage(csite,ipa) 
     csite%wbudget_initialstorage(ipa) = compute_water_storage(csite,lsl,ipa) 
     csite%ebudget_initialstorage(ipa) = compute_energy_storage(csite,lsl,ipa) 
    end do 

    return 
end subroutine update_budget 
!==========================================================================================! 
!==========================================================================================! 

我相處的

budget_utils.f90行錯誤信息:20.54:

真實的,外部:: compute_co2_storage 錯誤:(1)處的過程'compute_co2_storage'的僞參數'csite'具有需要此過程的顯式接口的屬性

(I ge一堆他們,但他們基本上都是一樣的)。現在,看着ed_state_vars.f90(這是「拿來主義」在子程序),我發現

!============================================================================! 
!============================================================================! 
    !---------------------------------------------------------------------------! 
    ! Site type: 
    ! The following are the patch level arrays that populate the current site. 
    !---------------------------------------------------------------------------! 

type sitetype 


    integer :: npatches 

    ! The global index of the first cohort in all patches 
    integer,pointer,dimension(:) :: paco_id 

    ! The number of cohorts in each patch 
    integer,pointer,dimension(:) :: paco_n 

    ! Global index of the first patch in this vector, across all patches 
    ! on the grid 

    integer :: paglob_id 

    ! The patches containing the cohort arrays 
    type(patchtype),pointer,dimension(:) :: patch 

等等等等 - 這又進了另一個500行左右。 因此,爲了能夠使用(虛擬)參數csite,似乎原始子例程需要其過程的顯式接口。再次,我對Fortran來說是最新的,但我真的很想了解它是如何「思考」的。我一直在尋找什麼意思,有一個明確的接口,何時(以及如何!)使用它等等。但我無法弄清楚它是如何適用於我的情況。我應該使用不同的編譯器(英特爾?)。任何提示?

編輯:那麼csite聲明中的所有程序target和聲明type(site type)包含一大堆pointer S,在sitetype規定。但在所有程序中,sitetype正在從另一個模塊(ed_state_vars.f90)正確地use d。所以我仍然困惑爲什麼它給了我明確的接口錯誤?

+0

您的模塊中有'compute_water_storage'和其他函數嗎? – SethMMorton 2013-05-10 19:45:22

+1

我們需要在'compute_co2_storage()'中看到'csite'的聲明,因爲錯誤消息是指該例程中聲明的屬性,而不是'update_budget()'中的聲明屬性。我懷疑它被聲明爲「可選」或「POINTER」或類似的東西。 – Deditos 2013-05-10 20:56:55

+0

感謝您的所有反饋。 @SethMMorton:是的,作爲「真正的功能」。 @Deditos:在'compute_co2_storage()'中,'csite'聲明和我在發佈的子例程中一樣:'type(sitetype),target :: csite'。 – Geraldine 2013-05-13 13:48:53

回答

13

「顯式接口」意味着程序的接口(子程序或函數)被聲明給編譯器。這允許編譯器檢查過程調用和實際過程之間參數的一致性。這可以發現很多程序員的錯誤。你可以用interface語句寫出接口,但是有一種更簡單的方法:將程序放入一個模塊中,並將其從任何其他調用該模塊的實體放入該模塊中 - 從主程序或本身不存在的任何過程在模塊中。但是,您不需要在同一模塊中使用另一個程序的程序 - 它們會自動相互知道。

將過程放置到模塊中會自動使其接口爲編譯器所知,並且可以在編譯時自動進行交叉檢查。這比編寫接口更容易,也更不容易出錯。使用接口,您必須複製過程參數列表。然後,如果您修改程序,您還必須修改呼叫(當然!),但也要修改界面。

使用「高級」參數時需要顯式接口(interface語句或模塊)。否則,編譯器不知道產生正確的調用

如果您的過程是use ed,則不應使用external對其進行描述。在現代Fortran中使用external的用途非常少 - 因此,請刪除external屬性,將所有程序放入模塊中,然後將它們放入use中。

+0

儘管將百萬行模型轉換爲模塊可能相當困難。 – 2013-05-11 15:52:32

+0

我明白你在說什麼(很好的解釋,謝謝!)。而被調用的過程是文件中的「真正的函數」,所以我猜他們甚至不必被聲明爲「外部」?或者,因爲它們並不都是作爲一個模塊專門捆綁在一起的,他們仍然應該這樣做? (因爲是的,正如@Vladimir所說的,這是一個將所有東西都轉換爲模塊的太大模型...)。真正的函數使用來自其他文件的信息(參見我對原始問題的編輯),但它們使用'use'(以獲得'sitetype',用於聲明'csite')。 – Geraldine 2013-05-13 16:29:23

1

我遇到了同樣的問題,當我嘗試在我的Mac 10.9上安裝ED2時,遇到了同樣的問題。我通過包括模塊,在該文件中的所有子程序固定它,那就是:

module mymodule 
contains 
subroutine update_budget(csite,lsl,ipaa,ipaz) 
other subroutines ecc. 
end module mymodule 

同樣的事情必須做在包裝10至15的其他文件。 我編譯了所有文件並生成了相應的目標文件,但現在我收到了關於未定義符號的錯誤。不過,我懷疑這些與修改無關,所以如果有人有耐心,這可能是解決至少界面問題的一種方法。