In un programma di calcolo per la soluzione di sistemi di equazioni non lineari, ho un insieme di equazioni (che descrivono dei processi fisici) sotto forma di funzioni. A tempo di esecuzione, devo essere in grado di fornire all'algoritmo risolutivo un sub-set di queste equazioni e relative incognite sotto forma di una funzione vettoriale funcv con argomento un vettore di incognite x. Le equazioni-funzioni e le incognite da scegliere sono ottenute da un input file. Sto cercando un modo per poter selezionare, a tempo di esecuzione, le funzioni da passare alla procedura di risoluzione.
Il linguaggio che sto usando è il Fortran 95, ma prima che i programmatori C scappino a gambe levate, faccio loro un appello a fornirmi una soluzione nel loro linguaggio visto che ci sono ormai poche differenze dal punto di vista delle capacità fra il Fortran 95+ e il C (cercherò poi di fare io una "traduzione").
Segue un esempio "statico" della funzione finale, ovvero un esempio (perfettamente funzionante) in cui passo all'algoritmo risolutivo un fissato set di incognite ed equazioni (è incluso in un modulo).
Codice: Seleziona tutto
MODULE equations
IMPLICIT NONE
REAL, PARAMETER :: ONE = 1.
CONTAINS
!_______________________________________________________________________
FUNCTION funcv(x)
REAL(dp), DIMENSION(:), INTENT(IN) :: x
REAL(dp), DIMENSION(SIZE(x)) :: funcv
REAL(dp), PARAMETER :: mp = 1.5, pmec = 1445422., a = 0.746E5, b = 0.55E5
REAL(dp), PARAMETER :: pmi = 963329., Ta = 288., pa = 1E5, eta_is_c = 0.8
REAL(dp), PARAMETER :: k = 1.4, eta_m_t = 0.95 , eta_is_t = 0.85, Ts = 700.
REAL(dp), PARAMETER :: eta_m_c = 0.95, rho = 9.
!
! x(1): l'v/lv x(2): ps x(3): pc x(4): mu x(5): Tc
!
funcv(1) = ONE + ONE / (rho-ONE) * ( ONE-( x(2)/x(3) )**(ONE/mp) ) - x(1)
funcv(2) = x(4) * x(1) * pmi + x(3) - x(2) - a - b*x(4)*x(1) - pmec
funcv(3) = SQRT( Ta / x(5) ) * x(3) / pa - x(4)
funcv(4) = Ta * ( ONE + ONE/eta_is_c * ( ( x(3)/pa )**( (k-ONE)/k ) - ONE ) ) - x(5)
funcv(5) = eta_m_t * eta_is_t * Ts * (ONE - ( pa/x(2) )**( (k-ONE)/k ) ) - ( x(5)-Ta )/eta_m_c
END FUNCTION funcv
END MODULE equations
Per quello che riguarda la "selezione" delle incognite, ho pensato di condividere l'ambito di visibilità di tutti i parametri (i vari mp, pmec, a, b,... che nel caso statico sono all'interno della funcv) tra tutte le equazioni-funzione a disposizione e poi, in una procedura di "linking", usare un puntatore per collegare le x alle effettive grandezze fisiche che l'input file avrà indicato come incognite. Fin qui, almeno in teoria, potrebbe anche funzionare, ma non so come fare per le funzioni. Suggerimenti? C'è un modo più elegante per risolvere il problema? Come fanno i programmi di calcolo seri (ho cercato un po' nei sorgenti di Octave, ma mi ci sono perso in un niente)?
Come avrete intuito non sono un esperto di programmazione anche se ho una certa esperienza nella programmazione orientata al calcolo, per cui qualunque suggerimento per migliorare il processo è ben accetto.
Grazie per la pazienza di avermi letto fin qui!