2012-05-25 2 views
5

Я разрабатываю код Fortran для решения системы PDE.Хороший дизайн ООП для решателя с современным Fortran

Способ, которым он разработан прямо сейчас, заключается в том, что у меня есть тип Variable, который имеет несколько атрибутов, наиболее важным из которых является массив val, который сохраняет значение.

Теперь у меня также есть класс solver, который будет выполнять вычисления на variable. Я решил, что передача целого variable решателю и работа с variable%val каждый раз, когда я захочу его запустить (несколько тысяч раз во время exectution), будет неэффективной, поэтому я решил определить поля указателя в классе solver, чтобы связать решатель к соответствующей переменной. Например

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 

И модуль решателя

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 

В моей программе я определяю другую переменную для различных физических свойств и различных решателей, которые связаны с этими переменными, как я показал выше.

Я новичок в ООП вообще, так что мой вопрос в том, что это достойный дизайн? Особенно с точки зрения производительности. Как это соотносится с тем, чтобы сделать T просто массивом и передать его подпрограмме solve с точки зрения скорости? Есть ли регулярный способ сделать это?

+2

Я не вижу много смысла в указателе переменной. Просто передать его, как фиктивный аргумент, кажется мне более естественным. Это только один дескриптор массива, ничего плохого для производительности. –

ответ

5

Я работаю с функциями OO Fortran в течение года или около того, вот некоторые расширенные комментарии, маскирующиеся как ответ.

Если вас просто беспокоит необработанная скорость выполнения, вы, вероятно, в целом (и на основе аргумента и моего опыта, а не данных) лучше избегаете функций OO; но тогда во многих случаях можно сделать то же самое, что вам лучше избегать всего, что добавлено на язык после FORTRAN77.

Аргументы в пользу ОО сильнее, когда они основаны на вопросах разработки кода, понятности, расширяемости, такого рода вещи. Если это имеет значение для вас, вы должны подумать об использовании функций OO.

Как уже прокомментировал Владимир, нет смысла использовать указатель переменной. Не забывайте, что большинство реализаций Fortran действительно используют call-by-reference, чтобы избежать усилий копирования (больших объемов) данных.

Лично мне не нравится, как вы определили свою процедуру с привязкой к типу create. Я предпочитаю, чтобы осуществлять такого рода операции как функции, так что я могу написать такие строки:

t = solver%new() 

, а не на

call T%create() 

Примечание это предпочтение мой, и это более вопрос стиля, а не эффективности или правильности. Я замечаю, что вы не объявили намерения аргументов подпрограмме create; возможно, потому, что вы только разместили фрагмент кода.

Поскольку OO относительно новичок в Fortran (и, возможно, относительно незнакомый большинству людей, работающих в доменах, где широко используется Fortran), нет много полезного материала, который поможет нам принять его.Я бы порекомендовал Scientific Software Design. Это дает теме достойное освещение и аргументирует, почему научные и инженерные программисты должны принять OO.

+0

+1 Мне также нравится инициализация как функция, так как она подходит к конструкторам (хотя выделение памяти выполняется в другом месте). Иногда даже удобно создавать интерфейс к solwer% new с именем solver ant, а затем использовать 't = solver()' даже в тех случаях, когда инициализация стандартного производного типа недостаточна. –

+0

Танки много для ссылки на книгу, я постараюсь это удержать. – tiam

+0

в вашем 'solver% new()' пример, что такое 'solver'? Объект Solver? Или вы можете просто получить доступ к функциям типа таким образом? – weymouth

Смежные вопросы