2012-05-25 9 views
5

私はPDEシステムを解くためのFortranコードを設計しています。最新のFortranを使用したソルバー向けの良いOOPデザイン

今のところ設計されているのは、いくつかの属性を持つタイプVariableです。最も重要なのは値を格納する配列valです。

solverクラスもあり、variableで計算されます。私はvariable全体をソルバーに渡してvariable%valを実行すると(実行中に数千回)、非効率的であると考えたので、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 

私のプログラムにするために私が上記示したように、これらの変数に関連付けられている異なる物理的性質と異なるソルバのために別の変数を定義します。

私は一般的にOOPを初めて使用しています。だから、それはまともなデザインですか?特にパフォーマンスの観点から。これは、配列としてTを作成し、それをサブルーチンsolveに速度と比較するとどのように比較されますか?これを行うための定期的な方法はありますか?

+2

私は変数ポインタに多くの点が表示されません。それを仮引数として渡すだけで、私にとってもっと自然なようです。これは1つの配列記述子であり、パフォーマンスに悪影響はありません。 –

答えて

5

私は1年ほどFortranのオブジェクト指向の機能を使っていましたが、これは答えとして偽装されたいくつかの拡張コメントです。

あなたは単純に生の実行速度に関心を持つならば、一般的には(そしてデータではなく議論と私の経験に基づいて)おそらくOO機能を明確に操る方がよいでしょう。しかし多くの場合、FORTRAN77の後に言語に追加されたものがあれば、それをはっきりと操るほうがよいという同じ議論をすることができます。

OOを支持する議論は、コード設計、理解可能性、拡張性、そのようなことの問題に基づいて確立されると、より強くなります。これらのことが問題になる場合は、オブジェクト指向の機能を使用することを検討する必要があります。

Vladimirはすでにコメントしているので、変数ポインタの使用にはあまり意味がないようです。ほとんどのFortran実装は、(大量の)データをコピーすることを避けるために、特にコールごとに参照を行うことを忘れないでください。

個人的には、タイプバインドされたプロシージャcreateを定義した方法が個人的に嫌いです。私はずっと、私はこのような行を記述することができるように、機能などの操作のその種を実装することを好む:

t = solver%new() 

ではなく、あなたの

call T%create() 

ノートよりも、これは私の好みであり、それはより多くのです効率性や正確さよりもスタイルの問題。私はサブルーチンcreateの議論の意図を宣言していないことに気付きました。おそらくコードのスニペットを投稿しただけなのかもしれません。

OOはFortranにとって比較的新しいものであり(おそらく、Fortranが広く使われているドメインで働いているほとんどの人にはあまり馴染みのないものです)、それを採用する際に役立つ資料はあまりありません。Scientific Software Designをお勧めします。これは、話題にまともなカバレッジを与え、科学技術者プログラマーがなぜOOを採用すべきかについて議論している。

+0

+1私は関数としての初期化も好きです(他の場所でメモリの割り当てが行われていますが)。時には、ソルバーの名前を持つsolwer%newへのインタフェースを作成し、標準の派生型の初期化では十分でない場合でも、 't = solver()'を使用すると便利な場合もあります。 –

+0

タンクは本のリンクのためにたくさんありますが、私はそれを保留しようとします。 – tiam

+0

の 'solver%new()'の例で 'solver'とは何ですか?ソルバーオブジェクト?あるいは、このように型関数にアクセスできますか? – weymouth

関連する問題