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

3章 CommonMPの要素モデルを作成する
3.5 計算結果を 他の要素モデルへ送る
3.5.5 要素モデルへの実装


 いよいよ 「MyDynamicWaveModel」の計算結果を 別な要素モデルへ送信できる様にします。

 送信するパターンは次の2つを考えます。

 (1)下流端出力
    下流端からの流量と水位を出力します。
    セルは1個で済むので ポイント時系列形式(McTranInfoDefine.SINGLE_CELL_SERIAL)とします。

 (2)断面出力
    河道全断面の流量、水位、流速を出力します。
    河道内の全区間分のセルを準備するため、1次元時系列(McTranInfoDefine.D1_CELL_SERIAL)とします。

 送信パターンを決めた所で、この送信パターンを実現するためのコーディングを行います。



(1)送信パターンの設定

 送信パターンにはそれを識別するIDが必要です。 このIDはコーディング時に 再々使用するので、 Defineクラスに定義しておきます。

public class MyExerciseModelDefine
{
  ・・・・
        /// <summary>下流端出力</summary>
        public static readonly HySID OUT_PATTERN_BOTTOM = new HySID("BottomOut");
        /// <summary>全セル内容出力</summary>
        public static readonly HySID OUT_PATTERN_ALL = new HySID("AllCellOut");
  ・・・・
}


  次に、Factoryクラスの McCellModelPropertyIF CreateModelProperty(HySID csLibraryID, HySObjectKind csModelKind)メソッド内で、
 プロパティ情報に 送信パターンを設定します。

 McCellModelPropertyIF CreateModelProperty(HySID csLibraryID, HySObjectKind csModelKind)
{
            if (csModelKind.Equals(MyExerciseModelDefine.MY_DYNAMIC_MODEL_KIND) == true)
            {
                csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);

                csRtnCellPrptyDt.SetStepTime(60); // δT設定 60秒
                csRtnCellPrptyDt.AddInfoType("XL", "河道長", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("XL", 100.0 * 1000.0);
                csRtnCellPrptyDt.AddInfoType("NX", "モデル内セル分割数+1", McDefine.ValKind.LONG);
                csRtnCellPrptyDt.SetInfo("NX", 50);
                csRtnCellPrptyDt.AddInfoType("ROUGH", "粗度", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("ROUGH", 0.03);
                csRtnCellPrptyDt.AddInfoType("SLOPE", "河床勾配", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("SLOPE", 1.0 / 2000.0);

                // 送信パターンの設定
                
                    // 第1パターン
                    McTranInfoPattern csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        MyExerciseModelDefine.OUT_PATTERN_BOTTOM,
                        McTranInfoDefine.SINGLE_CELL_SERIAL,
                        "下流端出力") as McTranInfoPattern;
                    
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(2);
                        
                            csCellChara.SetDataKind(0, "流量", HySDataCharacteristicInCell.DATA_KIND.QUANTITY_OF_WATER_FLOW, "m3/sec");
                            csCellChara.SetDataKind(1, "水位", HySDataCharacteristicInCell.DATA_KIND.WATER_LEVEL, "m");
                        
                        csTrnPtn.SetCellDataCharacteristic(csCellChara); // セル情報設定
                    
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn); // パターンの追加

                    // 第2パターン
                    csTrnPtn = csRtnCellPrptyDt.CreateTranInforPattern(
                        MyExerciseModelDefine.OUT_PATTERN_ALL,
                        McTranInfoDefine.D1_CELL_SERIAL,
                        "断面出力") as McTranInfoPattern;
                    
                        // セル内変数設定
                        HySDataCharacteristicInCell csCellChara = csTrnPtn.CreateCellDataCharacteristic(3);
                        
                            csCellChara.SetDataKind(0, "流量", HySDataCharacteristicInCell.DATA_KIND.QUANTITY_OF_WATER_FLOW, "m3/sec");
                            csCellChara.SetDataKind(1, "水位", HySDataCharacteristicInCell.DATA_KIND.WATER_LEVEL, "m");
                            csCellChara.SetDataKind(2, "流速", HySDataCharacteristicInCell.DATA_KIND.SCALOR_VELOCITY, "m/sec");
                        
                        csTrnPtn.SetCellDataCharacteristic(csCellChara); // セル情報設定
                    
                    csRtnCellPrptyDt.AddSendPattern(csTrnPtn); // パターンの追加
               


    (送信パターン設定の確認)

 送信パターンの設定がなされたことを確認するため 「MyDynamicWaveModel」にモニター画面を接続します。( 「下流端出力」パターンの確認として、時系列モニターを、 「断面出力」パターン確認として、1次元断面モニターを接続します。 )
 そこで、接続線のプロパティ画面を開き、接続パターンが設定されていればOKです。

    



(2)要素モデル:出力側の接続情報チェック

 要素モデル:SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)メソッドの中で、送信線の設定値として明らかにエラーとすべき点を指摘し、エラー情報/警告情報を返します。 
 
 「MyDynamicWaveModel」要素モデルの出力で、明らかにエラーとなるのは、断面出力の時、 モデル内の分割数よりもセルの数が少ない時です。また、出力が全くない場合も ワーニングを出したいと思います。 

 最初に接続線の数を調べます。
 0本であれば、 ”出力側に接続が有りません” というメッセージを出します。
 出力するメッセージを 引数で与えられた McStructErrorInfo クラスに追加します。
 AddCheckInformationData メソッドの
  第1引数は、要素モデルのID( CommonMP内で、全ての要素モデルはユニークなID値を持っています。 this.GetID() として取得できます。)
  第2引数は、要素モデルの種別( 自分で MyExerciseModelDefine クラス内に定義した値 )
  第3引数は、表示すべき文字列で任意の文章が書けます。

protected override bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
{
        bool bRtn = true;
        if (lOutputDataNum == 0)
        {
                csErrorInf.AddCheckInformationData(this.GetID(), MyExerciseModelDefine.MY_DYNAMIC_MODEL_KIND, "出力側に接続が有りません。");
        }

 次に接続線のパターンと配列数を取得し、 セル配列数が不足していれば、エラーメッセージを出し、リターンコードを false に設定します。
 ここで、示されている方法は 既に 前頁で示した方法です。
 要素モデル内の 分割数は m_csMyInf.NX+1 なので エラーとなる条件は
  if (lDim1 <= m_csMyInf.NX) で判断します。
  
 今回のメッセージの設定は エラーなので、引数で与えられた McStructErrorInfo クラスのAddCheckErrorData メソッドを使用します。 メソッド引数はAddCheckInformationData メソッドの場合と同じです。

protected override bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
{
    。。。。。。。。。。。。。

            long lDim1 = 0;;
            long lDim2 = 0;
            long lDim3 = 0;
            long lDimInCell = 0;
            HySID csSndPttnID;
            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。

                // 送信パターンIDを取得します
                csSndPttnID = csOutputCellData[lLp].GetSendPatternID();

                // 断面出力パターンならば
                if (MyExerciseModelDefine.OUT_PATTERN_ALL.Equals(csSndPttnID) == true)
                {
                    // 配列数を取得
                    csOutputCellData[lLp].GetDimension(ref lDim1, ref lDim2, ref lDim3, ref lDimInCell);

                    if (lDim1 <= m_csMyInf.NX)
                    {   // セル配列不足
                        csErrorInf.AddCheckErrorData(this.GetID(), MyExerciseModelDefine.MY_DYNAMIC_MODEL_KIND, "出力の配列数が不足しています。");
                        bRtn = false; // エラー設定
                    }
                   
                }


   (送信チェック動作の確認)

 送信チェックが正常に動作するかを確認します。 ソースをコンパイルし、ディバッグモードでCommonMPを立ち上げてみます。 下記の通りモデルを接続し、 CommonMPの「モデルチェック」を行います。

      


 モデルをチェックした時に、断面出力側接続線内のセル数が少ないと チェックエラーとなります。


       

 また、要素モデルの接続を全て外すと、ワーニングが表示されます。

       
 

 もしも意図した通りに動作しない場合には、プログラム動作中にブレークポイントを設定しておき、ステップ実行させて 不良箇所を発見して下さい。

      (ステップ実行)
    




(3)演算結果の出力

 3.4章で作成した要素モデル「MyDynamicWaveModel」は 計算結果をファイルに出力していましたが、此処ではそれを他の要素モデルに送ります。
 送信パターンは2種類定義したので、それぞれのパターンについて 出力する処理を実装する必要があります。

 下流端出力パターン

 要素モデルの最後のブロックの流量と水位を出力します。 モデルの最終ブロックの番号はm_csMyInf.NXです。 この位置のQとHの値を セルに設定します。 

protected override long DataFusion(long lOutputDataNum, ref McSendCellDataIF[] csOutputCellData)
{
            HySID csSndPttnID;
            HySCellData[] csSndCellData = null;
            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。

                csSndPttnID = csOutputCellData[lLp].GetSendPatternID();

                if (MyExerciseModelDefine.OUT_PATTERN_BOTTOM.Equals(csSndPttnID) == true)
                {  // 下流端出力ならば
                    csSndCellData = csOutputCellData[lLp].PrepareSendCellD1();
                   
                    csSndCellData[0].m_dData[0] = m_csMyInf.Q[m_csMyInf.NX];
                    csSndCellData[0].m_dData[1] = m_csMyInf.H[m_csMyInf.NX];
                } 



 断面出力パターン

 準備された1次元セル配列に 要素モデルの全ブロックの流量、水位、流速値を設定します。

protected override long DataFusion(long lOutputDataNum, ref McSendCellDataIF[] csOutputCellData)
{
            HySID csSndPttnID;
            HySCellData[] csSndCellData = null;
            for (long lLp = 0; lLp < lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。

                csSndPttnID = csOutputCellData[lLp].GetSendPatternID();

                if (MyExerciseModelDefine.OUT_PATTERN_BOTTOM.Equals(csSndPttnID) == true)
                {  // 下流端出力ならば
                           。。。。。。。。。
                } 
                else if (MyExerciseModelDefine.OUT_PATTERN_ALL.Equals(csSndPttnID) == true)
                {  // 断面出力パターンならば
                    csSndCellData = csOutputCellData[lLp].PrepareSendCellD1(); // 送信用セルを用意
                    for (long lCellNo = 0; lCellNo <= m_csMyInf.NX; lCellNo++)
                    {
                        csSndCellData[lCellNo].m_dData[0] = m_csMyInf.Q[lCellNo];
                        csSndCellData[lCellNo].m_dData[1] = m_csMyInf.H[lCellNo];
                        csSndCellData[lCellNo].m_dData[2] = m_csMyInf.V[lCellNo];
                    }
                }
                else
                {
                    // Do Nothing
                }



   (送信動作の確認)

 ディバッグ動作させてみて 要素モデルの計算結果を 実際にモニター画面上に結果を表示させてみます。 送信が正常に動作していれば 下のようなグラフが描かれるはずです。


 

 もし 期待と異なる結果となった場合、ブレークポイントを設定し、ステップ実行させて ディバッグを行います。



(雑談)
 出力メソッドの名前(DataFusion)について
 CommonMPの要素モデルで 計算結果を出力するメソッド名は 「DataFusion」です。 数々の要素モデルが計算を行い、それぞれ計算した結果が 出力時に混ざり合って より高度な意味を持つ情報に生まれ変わるという意味で そのような名称にしましたが、 送信者と受信者が1:1に決っている構造を考えると、単純に 「DataOut」の方が解り易かったかもしれません。 全ての情報が統合される様な接続方法(例えば、1対多、多対1、多対多の様な接続方法)が導入されると もう少し「DataFusion」らしくなるかもしれません。 


(注意)
 同一送信パターンが複数本出ることも可能です。
 この場合、注意して頂きたいのは、下図の様に同一送信パターンの送信線が2本出ても、それは決して分岐ではなく、単に情報を送信する先が2箇所あるという事です。 
 つまり、送信情報は2本とも計算によって算出された情報をそのまま送信します。(接続線が2本あっても 1/2にはしません。)
    


 ここで作成した要素モデル開発プロジェクト(Ex05_MyExerciseModel.lzh

 ダウンロードしたら解凍して生成されたフォルダー「MyExerciseModel」を \CommonMP\Source\HYMCO\OptionImpl\ 下に置きます。   
 解凍して生成されたプロジェクト:MyExerciseModel.csproj を ディバッグ用ソリューションに追加し、スタートアッププロジェクト(TestModelDeveloperMainExp)の依存関係に追加します。

 

 またテスト用のCommonMP計算プロジェクト(Ex05_MyExerciseStep1.lzh

 解凍して生成された、「MyExerciseStep1」フォルダーを \CommonMP\CommonMPData\ 下に置きます。

 




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

 

初版:2013/06/23 |