next up previous
: 2. 要素モデルの作成例 : OHyMoS の要素モデルの作成法 : OHyMoS の要素モデルの作成法

1. 要素モデルの作成方法

定義することを義務づけられている関数に関するさらに詳しい解説が,後の「純 粋仮想関数」の項にあります。

以下に、要素モデルの header file の作成方法を記述します。

  1. クラス Element を継承します。必ず、そうする必要があります。

  2. 受信端子をデータメンバとして宣言します。 (注1)

  3. 受信端子を登録する関数 void Register_receive_ports(void) を定義します (定義すること を義務づけられています)。

  4. 送信端子をデータメンバとして宣言します。

  5. 送信端子を登録する関数 void Register_send_ports(void) を定義します (定義することを義務づけられています)。

  6. パラメタをデータメンバとして宣言します。

  7. 状態量をデータメンバとして宣言します。

  8. 必要なら作業用に変数を宣言します。

  9. パラメタをファイルから読み込む関数 void Set_parameter(FILE* fp) を定 義します (定義することを義務づけられています)。

  10. パラメタを引数で与える関数を定義します。(必須ではありませんが,定義 するのが望ましい。部分系モデルを作成するときに役立ちます。)

  11. 初期値をファイルから読み込む関数 void Set_initial_state(FILE* fp) を定義します (定義することを義務づけられています)。

  12. 初期値を引数で与える関数を定義します。(必須ではありませんが,定義 するのが望ましい。部分系モデルを作成するときに役立ちます。)

  13. 最終状態をファイルに書く関数 void Save_terminal_state(FILE* fp) を 定義します (定義することを義務づけられています)。

  14. 最終状態を引数で指定する変数にコピーして戻る関数を定義します。(必須 ではありませんが,定義するのが望ましい。部分系モデルを作成するときに役立 ちます。)

  15. 安全のため,要素の代入を禁止するために,代入演算子を宣言だけして, 実装しません。 (注2)

  16. コンストラクタとデストラクタを定義します。

    a. 受信端子や送信端子には,オブジェクト名とオブジェクト番号を与えるよう にします。 (注3)

    b. クラス名を格納する変数 class_name にクラス名を設定します。

    c. 要素モデルに,オブジェクト名とオブジェクト番号を与えることができるよ うにします。

  17. 初期出力関数 Boolean Initial_output(void) を定義します。(必須)

  18. 計算時間間隔を計算する関数 time_t Calculate_time_step(void) を定義 します (定義することを義務づけられています)。 (注4)

  19. 計算をすることができるかを判断する関数 Boolean Can_you_calculate(void) を定義します。 (定義することを義務づけられていま す)。 (注5)

  20. 一ステップの計算をする関数 Boolean Calculate(void) を定義します。 (定義することを義務づけられています)。

  21. 初期化後の一連の計算・出力作業をする関数 Boolean Work(void) を定義 します (定義することを義務づけられています)。

  22. 不要になったデータを削除するときに使う関数 time_t Necessary_time_from(Receive_port* rp) を定義します。 (注6)

  23. 直接通信を利用してパラメタなどの情報を共有するための関数 Boolean Share_info(void) を定義します(必要なければ定義しなくてもかまい ません)。 (注7)

  24. 直接通信を利用して要素間反復計算を行なう要素モデルを作成する 場合は、(23) までの作業に加えて、いくつかの仮想関数を再定義する などの作業が必要となります。詳しくは、doc/iterate.doc をご覧下さい。

(注1) 受信端子・送信端子の配列へのポインタをデータ メンバとして宣言することも考えられます。その場合は,要素モデルのコ ンストラクタで,受信端子・送信端子の配列を new で確保するようにし ます。

(注2) 要素モデルを代入する必要はないはずです。代入 演算子を宣言だけして,実装しないでおくと,ユーザが誤って代入操作を するようなコードを書くと,コンパイラがエラーメッセージを出します。

(注3) 受信端子には "rp", 送信端子には "sp" という オブジェクト名を与え,オブジェクト番号は 0 から始めることに決めて おくのが良いと思います。もちろん、このように決めることができない場 合もあり、その場合は適当に決めてもかまいません。

(注4) Calculate_time_step は, メンバ関数 Work の オプションとして用意されている Work0 の中で呼ばれています。Work1 を使う場合や, 独自に Work を定義する場合には, Calculate_time_step が呼ばれないこともあり得ます。そういう場合は,

time_t Calulate_time_step(void) return 0;

などの便宜的な定義をしておいてください。

(注5) Boolean Can_you_calculate(void) は,計算を するために必要なデータが取得できるかを判断する関数です。ユーザが自 分で, Can_you_calculate を定義しても構いませんが, オプションとし て, つぎの2つの関数が用意されています。

Can_you_calculate0(void)

Element のメンバ関数 Necessary_time_from, Necessary_time_to で定 義される時間の間のデータが取得できれば計算可能と判断する。これを 選ぶのが自然です。Necessary_time_from, Necessary_time_to 関数は、 ユーザが自由に再定義できますが、デフォールトでは、 Necessary_time_from は current_time を返し、Necessary_time_to は、 current_time + time_step の値を返します。

Can_you_calculate1(void)

Necessary_time_from で定義されるデータが取得できれば計算可能と判 断します。(この場合は、Necessary_time_to 関数を定義する意味はあ りません。)

たとえば, Can_you_calculate0(void) を選ぶなら,

Boolean Can_you_calculate(void) return Can_you_calculate0();

と定義すればよいです。

メンバ関数 Can_you_calculate は, メンバ関数 Work のオプションとして用意 されている関数 Work0, Work1 の中で呼び出されています。ユーザがこれらのオ プションを採用せず, 独自に, メンバ関数 Work を定義する場合には, メンバ関 数 Can_you_calculate は呼び出されないということもあり得ます。しかし, そ れでも, メンバ関数 Can_you_calculate は純粋仮想関数ですから, 定義する必 要があります。

部分系 Sub_system の Work では, Can_you_calculate を呼び出しません。です から, メンバ関数 Can_you_calculate の定義には特に意味はありません。部分 系のヘッダファイル sub.h では, デフォールトの定義として,

Boolean Can_you_calculate(void) return YES;

が与えられています。

Can_you_calculate は、Calculate を実行する前に、計算するためのデータが入 手できるかを確認するために呼び出されます。場合によっては、データが入手で きるかを事前に判断せずに、Calculate を実行していく中で、その判断をしたい 場合もあり得ます。その場合は、Can_you_calculate は常に YES を返すように 定義しておけばよいでしょう。そして、Calculate を実行していく途中で、デー タが入手できなくて計算を続けることができなくなった時に、Calculate が戻り 値として、NO を返すようにするとよいでしょう。

(注6) デフォールトでは、Necessary_time_from は、 受信端子に関係なく、current_time を返すように定義されています。こ の定義でもいい場合には、変更する必要はありません。

(注7) Share_info は、直接通信を利用してパラメタな どの情報を共有するための関数です。様々な利用方法が考えられますが、 たとえばあるオブジェクトのパラメタを他のオブジェクトでも利用したい 場合などに利用できます。それぞれが同じパラメタを Set_parameter で 設定するのではなく、一方が設定したパラメタ値を、他方がコピーさせて もらう、あるいはそのパラメタへのポインタを教えてもらう、などといっ た使い方が考えられます。情報を共有する作業を行った場合は YES を返 して下さい。作業を行えなかった場合は NO を返して下さい。デフォルト では単に YES を返すように定義しています。

Share_info は Element::Do_share_info から呼ばれます。 Element::Do_share_info は、Sub_system::Do_share_info あるいは Total_system::Do_share_info から呼ばれます。Element, Sub_system, Total_system の Do_share_info は仮想関数となっていますが、ユーザーが 再定義する必要はないと思います。また、Share_info を利用する要素モデル が一つもないのなら、メインプログラムで全体系モデルの Do_share_info を 呼ぶ必要はありません(呼んでも何ら問題はありませんが)。 もし、Share_info を利用する要素モデルが一つでもあれば、メイン プログラムで全体系モデルの Do_share_info を呼んで下さい。


next up previous
: 2. 要素モデルの作成例 : OHyMoS の要素モデルの作成法 : OHyMoS の要素モデルの作成法
Michiharu SHIIBA
平成12年10月13日