(前頁)<<      >>(次頁)          (Up)

4章 CommonMPにおける計算制御 その1
4.5 制御に関連する注意/補足事項 
    (送信するデータの時刻の独自設定)


 この頁は、初心者向けの内容ではないので、必要のない方は読み飛ばして下さい。
   (より高度な要素モデルを作成する必要が生じた時に参考にして下さい)



(1) 送信するデータの時刻を独自で設定する方法

 要素モデルからデータを送信する際、送信データには 要素モデル内の現在のシミュレーション時刻(m_csSimTime) が自動的に設定されます。 しかし、処理によっては、現在のシミュレーション時刻以外の情報も送信したい場合があるかもしれません。 
 現在時刻:T として、 δt 前の時刻、δt 後の時刻の 各データを送信する場合を例にとり 任意の時刻の情報を送信する方法を説明します。

 送信側接続線に対して、あるデータを送信する手順は 次の4つの手順で一纏まりです。

@送信する時刻データをセットする。 (SetCurrentTimeメソッド)
A送信するデータを格納するレコードを生成する。(PrepareSendCellD1メソッド等)
Bレコード内のセルに送信するデータを設定する。
Cレコードを 送信する回線に追加する。(SendData メソッド)


 通常はAとBの処理を派生クラス側で行い、@、Cの処理は 親クラス側で行なっています。 
 親クラスでは、@に設定する時刻は 現在のシミュレーション時刻(m_csSimTime)です。

 そこで、任意の時刻を送信する場合には、 上記@〜Cの処理を自前で行えば良いということになります。

 送りたい時刻が 現在時刻より δt 前の時刻:prvTime であるときには、以下の様なコーディングになります。

McSendCellDataIF[] csOutputCellData ←引数

    HySTime prvTime = this.m_csSimTime - this.m_csDltTime;
    csOutputCellData[lLp].SetCurrentTime( prvTime );  // 時刻を prvTime に設定

    // ↓↓ 以降は通常の処理と同じ ↓↓
         HySCellData[] csSndCellData;
         csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // レコードを生成(1次元配列の場合)
         csSndCellData[0].m_dData[0] =   。。。。。セルに情報を設定する
          ・・・・・・・

 同様に 現在時刻よりも δt 後の時刻:nxtTime

McSendCellDataIF[] csOutputCellData ←引数

    HySTime nxtTime = this.m_csSimTime + this.m_csDltTime;
    csOutputCellData[lLp].SetCurrentTime( nxtTime );  // 時刻を nxtTime に設定

    // ↓↓ 以降は通常の処理と同じ ↓↓
         HySCellData[] csSndCellData;
         csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // レコードを生成(1次元配列の場合)
         csSndCellData[0].m_dData[0] =   。。。。。セルに情報を設定する
          ・・・・・・・



 δt前、 現在、 δt後 の3レコードを設定する時には次のように行います。

 

McSendCellDataIF[] csOutputCellData ←引数

//δt前の時刻のデータを送信
    HySTime prvTime = this.m_csSimTime - this.m_csDltTime;
    csOutputCellData[lLp].SetCurrentTime( prvTime );  // 時刻を prvTime に設定

    // ↓↓ 以降は通常の処理と同じ ↓↓
         HySCellData[] csSndCellData;
         csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // レコードを生成(1次元配列の場合)
         csSndCellData[0].m_dData[0] =   。。。。。セルに情報を設定する
         
    csOutputCellData[lLp].SendData();  // 接続線にレコードを追加する。


// 現在時刻のデータを送信
    csOutputCellData[lLp].SetCurrentTime( this.m_csSimTime );  // 時刻を 現在時刻 に設定
    // ↓↓ 以降は通常の処理と同じ ↓↓
         HySCellData[] csSndCellData;
         csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // レコードを生成(1次元配列の場合)
         csSndCellData[0].m_dData[0] =   。。。。。セルに情報を設定する
         
    csOutputCellData[lLp].SendData();  // 接続線にレコードを追加する。
 

// δt後のデータを送信
    HySTime nxtTime = this.m_csSimTime + this.m_csDltTime;
    csOutputCellData[lLp].SetCurrentTime( nxtTime );  // 時刻を nxtTime に設定

    // ↓↓ 以降は通常の処理と同じ ↓↓
         HySCellData[] csSndCellData;
         csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // レコードを生成(1次元配列の場合)
         csSndCellData[0].m_dData[0] =   。。。。。セルに情報を設定する
          ・・・・・・・
    // 最後のレコードには csOutputCellData[lLp].SendData(); を 行わないことに注意( 親処理で行う為)

 
 ところで、任意の時刻のデータを送信した時、「最後に送信した時刻より未来の情報は全て破棄される」という事柄に注意する必要があります。
 例えば、既に接続線に次の時刻の3レコードが追加されているとします。
     09:23:00, 09:24:00, 09:25:00
 ここで、 09:23:30 のレコードを追加します。
 すると、09:23:30 より未来の情報は全て破棄され、 接続線上のレコードは
     09:23:00,09:23:30 
 の 2レコードだけになります。(同一時刻のレコードがあれば、そのレコードも破棄されます。)
 レコードが 新旧のレコードの間に挿入されることはありません。

 複数個のレコードを続けて送信する場合には、必ず古い時刻の情報から送信して下さい。
 
 注意
  この方法を用いると CommonMPの時刻の進め方からズレますので、使用する時には十分に注意が必要です。
  接続の前後の要素モデルの処理内容を供に良く知っておく必要があるでしょう。


(2) 計算条件を判断するメソッド

 要素モデルが計算しようとする時に必要とする情報が揃っていなかった場合(例えば前頁の未来予測型:4 T+δt計算)には 計算メソッド(Calculateメソッド)がコールされないようにCommonMP側で制御していると説明しましたが、実際には、計算条件が揃っているか否かを 要素モデルに対して問い合わせています。 CommonMPは 要素モデルからの応答が「計算不要(または、不能)」の時には 計算(Calculate)を呼ばないようにしています。
 この問い合わせメソッドをオーバーライドすると、要素モデル側で 計算の条件をある程度コントロールすることが可能となります。

 要素モデルが準備している 計算条件の判断を行うメソッドは IsConverged() メソッドです。
 IsConverged()メソッドの戻り値が true の場合には、要素モデルは 計算(Calculate)を行いません。

 親クラスは IsConverged()メソッド内で次の様な判断を行なっています。

 ・目標時刻に到達したか? 目標時刻に到達していれば true を返す。(これ以上の計算は不要)
 ・前に接続されている要素モデルからの出力レコードの最終時刻は 自要素モデル内のシミュレーション時刻とくらべて新しいか?
  (同期/非同期、 現在/未来型で 多少異なりますが、 大枠ではこのような判断です)
  もし、現在時刻よりも古い情報しかなければ、true を返す。(計算が不能)


 派生クラスでオーバーライドする時には 次のようなコーディングイメージになります。
public override bool IsConverged( )
{
        bool bRtn = base.IsConverged( ); // 親クラスのIsConverged()処理を行わせる
        if( bRtn != true )
       {   // 親クラスの判断では 計算が必要と判断された場合
               // 独自の判断を加えて bRtn の値を設定する
        。。。。。。。。。
        }
        return bRtn ;
}

 


 コーディングの中で this.m_csSimTime の様に "this" が使用されていますが、this は自分自身を表すキーワードです。 this は省略可能です。 
 一方、base.IsConverged( ); の様に "base"は 親クラスを意味します。 オーバーライドしたメソッド内で 親クラスのオーバライド前の処理をコールしたい時等で用います。.

 



(前頁)<<      >>(次頁) 

初版:2013/06/26 |