MPIアプローチの代わりに、呼び出し間の状態を記憶するためにプログラムBが知る必要のあるすべての変数を含むオブジェクト(派生型)を設計することもできます。次に、プログラムBの機能を次の3つのルーチンに分割する必要があります。
- 初期化ルーチン(Aの最初のタイムステップの前に呼び出されます)
- メインルーチン(Aの各タイムステップで呼び出されます)
- オプション:破棄(Aの最後のタイムステップの後に呼び出されます)。
プログラムAからこれらのルーチンのいずれかを呼び出すたびに、変数を使用して派生型を渡します。最初の呼び出しで初期化され、後続の呼び出しで使用されます。
したがって、プログラムAは次のようになります。
type(bdata) :: myb
...
call initialize_b(myb)
do ii = 1, ntimesteps
...
call main_b(myb, data)
...
end do
call destruct_b(myb)
タイプbdata
には、プログラムBが覚えておく必要のあるすべてのものが含まれている必要があります。
type :: bdata
integer, allocatable :: whatever(:)
...
end type bdata
また、プログラムBの機能を備えたモジュール内のルーチンは次のようになります。
!> First initialization of B (slow).
subroutine initialize_b(myb)
type(bdata), intent(out) :: myb
...
end subroutine initialize_b
!> Process data comming from program A.
subroutine main_b(myb, data)
type(bdata), intent(inout) :: myb
...
end subroutine main_b
プログラムBのインスタンスが1つだけ必要な場合は、プログラムBを(派生型のフィールドではなく)その状態を格納するモジュール変数を持つモジュールに変換することで、同じトリックを実行できます。しかし、どのような解決策をとっても、初期化部分を何らかの方法で分離して、一度だけ実行されるようにする必要があります。