2012-05-25 18 views
5

Projektuję kod Fortrana do rozwiązania systemu PDE.Dobry projekt OOP dla solvera z nowoczesnym Fortranem

Sposób, w jaki został zaprojektowany, polega na tym, że mam typ Variable, który ma kilka atrybutów, z których najważniejszą jest tablica val, która przechowuje wartość.

Teraz mam również klasę solver, która wykonuje obliczenia na variable. Pomyślałem, że przekazanie całego variable do solver i pracy z variable%val za każdym razem, gdy chcę go uruchomić (kilka tysięcy razy podczas egzekucji) byłoby nieefektywne, więc zdecydowałem się zdefiniować pola wskaźnika w klasie solver, aby powiązać z solver do odpowiedniej zmiennej. Na przykład

program example 
    use variable 
    use solvers 

    type(Variable) T 
    type(Solver) solver_temperature 

    !Contructors 
    call T%create() 
    call solver_temperature%create(T) 

    call solver_temperature%solve() 
end program example 

i moduł Solver

module solvers 
type Solver 
    real*8, pointer :: T(:,:) 

contains 
    procedure :: create 
    procedure :: solve 
end type 

contains 
    subroutine create(this,T) 
     type(Solver) :: this 
     type(Variable) :: T 

     this%T => T%val 
    end subroutine 
end module 

W moim programie zdefiniować inną zmienną o różnych właściwościach fizycznych i różnych rozwiązują, które są związane z tymi zmiennymi w sposób pokazałem powyżej.

Jestem nowy w OOP w ogóle, więc moje pytanie brzmi, czy to przyzwoity projekt? Zwłaszcza z punktu widzenia wydajności. Jak to się ma do robienia z tablicą T i przekazywanie jej do podprogramu solve pod względem szybkości? Czy jest jakiś regularny sposób na zrobienie tego?

+2

Nie widzę wiele punktów w zmiennej wskaźnik. Samo przekazanie go jako fałszywej argumentacji wydaje mi się bardziej naturalne. Jest to tylko jeden deskryptor tablicy, nic złego dla wydajności. –

Odpowiedz

5

Pracuję z funkcjami OO Fortran od około roku, oto kilka rozszerzonych komentarzy podszywających się pod odpowiedź.

Jeśli chodzi po prostu o nieprzetworzoną prędkość wykonania, to prawdopodobnie generalnie (i na podstawie argumentów i moich doświadczeń, a nie danych), lepiej omijać funkcje OO; ale w wielu przypadkach można sformułować ten sam argument, że po FORTRAN77 lepiej jest omijać wszystko, co jest dodane do tego języka.

Argumenty przemawiające za OO są silniejsze, gdy opierają się na zagadnieniach związanych z projektowaniem kodu, zrozumiałością, rozszerzalnością, tego typu rzeczami. Jeśli to ci zależy, powinieneś pomyśleć o użyciu funkcji OO.

Vladimir już skomentował, nie wydaje się, aby używanie zmiennej było zbyteczne. Nie zapominaj, że większość implementacji Fortran wykonuje wywołania po adresie, aby uniknąć wysiłku związanego z kopiowaniem (dużych wolumenów) danych.

Osobiście nie podoba mi się sposób, w jaki zdefiniowałeś swoją procedurę związaną z typem create. Wolę, aby realizować tego typu działania jako funkcję, tak, że mogę pisać wiersze tak:

t = solver%new() 

raczej niż

call T%create() 

Uwaga jest to korzystne z kopalni, a to więcej kwestia stylu, a nie wydajności lub poprawności. Zauważam, że nie zadeklarowałeś zamiarów argumentów podprogramu create; być może dlatego, że opublikowałeś tylko fragment kodu.

Ponieważ OO jest nowością w Fortranie (i, zapewne, stosunkowo mało znanym osobom pracującym w domenach, w których Fortran jest powszechnie używany), nie ma zbyt wielu użytecznych materiałów, które mogłyby nas w tym pomóc.Polecam Scientific Software Design. Daje to tematowi odpowiedni zasięg i argumentuje, dlaczego naukowcy i inżynierowie powinni przyjmować OO.

+0

+1 Również podoba mi się inicjalizacja jako funkcja, ponieważ inne podejścia z konstruktorami (chociaż alokacja pamięci odbywa się gdzie indziej). Czasami jest nawet przydatny, aby utworzyć interfejs dla solwer% new za pomocą solvera nazwy ant, a następnie użyć 't = solver()' nawet w przypadkach, w których standardowa inicjalizacja typu pochodnego nie jest wystarczająca. –

+0

Czołgi często za link do książki, spróbuję to złapać. – tiam

+0

w twoim przykładzie 'solver% new()', czym jest "solver"? Obiekt Solver? Czy możesz po prostu uzyskać dostęp do funkcji typu w ten sposób? – weymouth