2013-05-10 15 views
5

Sono molto nuovo per Fortran, e per la mia ricerca ho bisogno di far girare un mostro di una modella, quindi sto imparando mentre sto andando avanti. Quindi mi dispiace se faccio una domanda "stupida". Sto cercando di compilare (Mac OSX, dalla riga di comando) e sono già riuscito a risolvere alcune cose, ma ora mi sono imbattuto in qualcosa che non so come risolvere. Penso di avere l'idea dietro l'errore, ma ancora una volta, non sono sicuro di come risolvere.Fortran - interfaccia esplicita

Il modello è enorme, quindi inserirò solo le sezioni di codice che ritengo rilevanti (anche se potrei sbagliarmi). Ho un file con diverse subroutine, che inizia con:

!==========================================================================================! 
! 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 
!==========================================================================================! 
!==========================================================================================! 

ricevo messaggi di errore lungo le linee di

budget_utils.f90: 20.54:

reale, esterno :: compute_co2_storage Errore: L'argomento fittizio 'csite' della procedura 'compute_co2_storage' in (1) ha un attributo che richiede un'interfaccia esplicita per questa procedura

(I ge un sacco di loro, ma sono essenzialmente tutti uguali). Ora, guardando ed_state_vars.f90 (che viene "usato" nella subroutine), trovo

!============================================================================! 
!============================================================================! 
    !---------------------------------------------------------------------------! 
    ! 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 

etc etc - questo vale uno per altri 500 linee o giù di lì. Quindi, per arrivare al punto, sembra che la subroutine originale abbia bisogno di un'interfaccia esplicita per le sue procedure per poter usare l'argomento (fittizio) csite. Ancora una volta, sono così NUOVO a Fortran, ma sto davvero cercando di capire come "pensa". Ho cercato cosa significa avere un'interfaccia esplicita, quando (e come!) Usarlo ecc. Ma non riesco a capire come si applica al mio caso. Dovrei forse usare un compilatore diverso (Intel?). Qualche suggerimento?

Edit: Quindi csite viene dichiarato un target in tutte le procedure e dalla dichiarazione type(site type) contiene un intero gruppo di pointer s, come specificato nella sitetype. Ma lo sitetype è correttamente use da un altro modulo (ed_state_vars.f90) in tutte le procedure. Quindi sono ancora confuso perché mi dà l'errore esplicito dell'interfaccia?

+0

Sono 'compute_water_storage' e le altre funzioni nel modulo? – SethMMorton

+1

Abbiamo bisogno di vedere la dichiarazione di 'csite' in' compute_co2_storage() 'perché il messaggio di errore si riferisce agli attributi dichiarati in quella routine piuttosto che in' update_budget() '. Sospetto che sia dichiarato "OPZIONALE" o "POINTER" o qualcosa del genere. – Deditos

+0

Grazie per tutto il feedback. @SethMMorton: sì, come 'funzione reale'. @Deditos: in 'compute_co2_storage()', 'csite' è dichiarato come nella subroutine che ho postato:' type (sitetype), target :: csite'. – Geraldine

risposta

13

"Interfaccia esplicita" significa che l'interfaccia alla procedura (subroutine o funzione) viene dichiarata al compilatore. Ciò consente al compilatore di verificare la coerenza degli argomenti tra le chiamate alla procedura e la procedura effettiva. Questo può trovare molti errori del programmatore. Puoi farlo scrivendo l'interfaccia con un'istruzione interface ma c'è un metodo molto più semplice: posiziona la procedura in un modulo e use quel modulo da qualsiasi altra entità che lo chiama - dal programma principale o da qualsiasi altra procedura che non sia esso stesso nel modulo. Ma non è una procedura da use da un'altra procedura nello stesso modulo - si conoscono automaticamente l'un l'altro.

L'inserimento di una procedura in un modulo rende automaticamente l'interfaccia nota al compilatore e disponibile per il controllo incrociato quando è use ed. Questo è più facile e meno incline agli errori rispetto alla scrittura di un'interfaccia. Con un'interfaccia, devi duplicare l'elenco degli argomenti della procedura. Quindi se rivedi la procedura, devi anche rivedere le chiamate (ovviamente!) Ma anche l'interfaccia.

Un'interfaccia esplicita (interface istruzione o modulo) è richiesta quando si utilizzano argomenti "avanzati".Altrimenti il ​​compilatore non sa di generare la chiamata corretta

Se si dispone di una procedura che è use ed, non è necessario descriverlo con external. Ci sono pochissimi usi di external nel moderno Fortran - quindi, rimuovere gli attributi external, inserire tutte le procedure in un modulo e use.

+0

Potrebbe essere piuttosto difficile convertire un milione di modelli di linea in moduli. –

+0

Capisco cosa stai dicendo (buona spiegazione, grazie!). E le procedure che vengono chiamate sono 'funzione reale' all'interno del file, quindi immagino che non debbano essere dichiarate come' esterne'? Oppure, dato che non sono tutti raggruppati in modo specifico come modulo, dovrebbero ancora? (perché sì, come dice @Vladimir, questo è un modello troppo grande per convertire tutto in moduli ...). La 'funzione reale' usa le informazioni da un altro file (vedi la mia modifica della domanda originale), ma usano' use' (per ottenere 'sitetype', che viene usato per dichiarare' csite'). – Geraldine

1

Mi sono imbattuto negli stessi problemi riscontrati mentre stavo cercando di installare ED2 sul mio Mac 10.9. Ho riparato includendo tutte le subroutine in quel file in un modulo, che è:

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

La stessa cosa doveva essere fatto per circa 10 o 15 altri file nel pacchetto. Ho compilato tutti i file e prodotto i file oggetto corrispondenti, ma ora ricevo errori sui simboli non definiti. Tuttavia, sospetto che siano indipendenti dalle modifiche, quindi se qualcuno ha la pazienza questo potrebbe essere un modo per risolvere almeno il problema dell'interfaccia.