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

6章 再び要素モデルの作成
6.3 上位要素モデルからの受信データの取り扱いに関する補足事項



 (3) KinematicWave河道要素モデルを 横からの入力も受信できるように改造する例

 これまで作成してきたKinematicWave河道要素モデルは 上流端からの入力だけに対応していました。 そこで、本ページでは当河道要素モデルに対して、2種類の横からの入力が可能なように 改修します。
 演習用の要素モデル作成プロジェクト「MyExerciseModel」に対して、これまでと同様の方法で、要素モデル「MyKinematicLateralModel」と 演算データ「MyKinematicLateralCalInfo」を追加し、スタブを作成します。 要素のモデル内処理の実装のために、すでに製作済みの「MyKinematicWaveModel」と「MyKinematicWaveCalInfo」の内容をそのままコピーしておきます(名称のみ変更)。 こうすることで、横入力処理追加のためには、何を改修すべきかを明確にすることができます。
 以降、新しく作成した要素モデル「MyKinematicLateralModel」と 演算データ「MyKinematicLateralCalInfo」を元にして、それに対する改修部分について説明する事にします。 ディファインファイルクラス(MyExerciseModelDefine)内に 新しい要素モデルの 種別と名称を定義しておきます。

        /// <summary>演習:KinematicWaveモデル種別</summary>
        public static readonly HySObjectKind MY_KINEMATIC_LATERAL_MODEL_KIND = new HySObjectKind("MyKinematicLateralWaveModel");
        /// <summary>演習:KinematicWaveモデル名称</summary>
        public static readonly HySString MY_KINEMATIC_LATERAL_MODEL_NAME = new HySString("演習:横入力有りKinematicWave河道モデル");


 今回追加したい機能は2種類あります。



 @ 
 
ひとつは ポイント時系列情報を横から入力する場合です。 モデルとしては下図のように、流域モデルからの下流端からの流量を受け取ります。 入力パターンのIDは MyExerciseModelDefine内に
        /// <summary>ポイント入力横入力端入力</summary>
        public static readonly HySID IN_PATTERN_D0_LATERAL = new HySID("LateralDim0In");
として 定義しておきます。


      

 モデル上で横入力1、2、3はそれぞれ異なる河道内のセルに接続されています。 各セルに設定されている外部ファイルは下記の通りとします。 
横入力1用 : D0Sample01SideIn.xml
<?xml version="1.0" encoding="UTF-8"?>
<CellIDMngFile>
  <CellManageTable Kind="McModelCellCorrespondenceInf" FileName="ParameterData\D0Sample01SideIn.xml">
    <TranCell IdxD1="0">
      <UpperModelCell IdxD1="0" />
      <LowerModelCell IdxD1="5" />
    </TranCell>
  </CellManageTable>
</CellIDMngFile>

横入力2用 : D0Sample02SideIn.xml
<?xml version="1.0" encoding="UTF-8"?>
<CellIDMngFile>
  <CellManageTable Kind="McModelCellCorrespondenceInf" FileName="ParameterData\D0Sample02SideIn.xml">
    <TranCell IdxD1="0">
      <UpperModelCell IdxD1="0" />
      <LowerModelCell IdxD1="24" />
    </TranCell>
  </CellManageTable>
</CellIDMngFile>

横入力3用 : D0Sample03SideIn.xml
<?xml version="1.0" encoding="UTF-8"?>
<CellIDMngFile>
  <CellManageTable Kind="McModelCellCorrespondenceInf" FileName="ParameterData\D0Sample03SideIn.xml">
    <TranCell IdxD1="0">
      <UpperModelCell IdxD1="0" />
      <LowerModelCell IdxD1="42" />
    </TranCell>
  </CellManageTable>
</CellIDMngFile>


 ポイント入力に対応する河道モデルは、次のように処理を実装します。

public class MyKinematicLateralModel : McForecastModelBase
{
        double[ ]  dLateralQin;  // 横入力一時保管(配列)
        //  ポイント入力が要素モデルのどのセルに入力するかを示す対応値:入力接続数分確保
        long[ ]  Dim0InLowerDim1;   // <-- メンバー変数として定義しておく

     。。。。。。。。。。。。。

    // モデルチェック時に 対応情報を格納しておく
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;

      。。。。。。。。。。。。

            McModelCellCorrespondenceInf csCellMng = null; // 上下要素モデル対応表
            McModelCellCorrespondenceInf.McCellIdxInf[] csCellIdx = null; // 具体的対応関係情報


            HySID csRcvPttnID;
            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。

                // 入力する伝送データの型式や設定値等をチェックし、一つでも期待情報でなければ、bRtn=false; を設定します。
                csRcvPttnID = csInputCellData[lLp].GetReceivePatternID();  // 受信パターン取得
                if (MyExerciseModelDefine.IN_PATTERN_TOP.Equals(csRcvPttnID) == true)
                {   // 上流入力の場合
                    // 何もしない
                }
                else if (MyExerciseModelDefine.IN_PATTERN_D0_LATERAL.Equals(csRcvPttnID) == true)
                {   // ポイント入力横入力端入力
                    csCellMng = csInputCellData[lLp].GetCellIDData() as McModelCellCorrespondenceInf;
                    if( csCellMng != null )
                    {   // 対応表ありならば
                        csCellIdx = csCellMng.GetCellIdxInf(ref lIdxInfNumber); // 接続セルを取得

                        // ポイント時系列であるため接続セルは1個である。 またこのモデルは1次元で受けるので2,3次元は不要
                        Dim0InLowerDim1[lLp] = csCellIdx[0].m_lLowerModelCellIndexDim1; // 上位からの入力がどのセルに入るかを記憶する
              // ↑ここで、各入力が 下位モデルの何番目のセルに入るかを記憶しておく
                    }
                    else
                    {
                        csErrorInf.AddCheckErrorData(csInputCellData[lLp].GetUpperElementID(), MyExerciseModelDefine.MY_DYNAMIC_MODEL_KIND, "接続情報ファイルの設定がされていません。");
                        bRtn = false;
                    }
                }
        。。。。。。。。。。。。。。。。。


        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {


            for (long lLp = 0; lLp <= m_csMyInf.NX; lLp++)
            {   // 横入力値を0リセットする
                dLateralQin[lLp] = 0.0;
            }

            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。
                csRcvPttnID = csInputCellData[lLp].GetReceivePatternID();  // 受信パターン取得
                csGetter = csInputCellData[lLp].GetCellDataGetter();  // 接続の対応表の取得
                lReadIdxQ = csGetter.GetIdx(0); // 実際に読む位置を取得(受信側は0番目が流量と認識している)

                if (MyExerciseModelDefine.IN_PATTERN_D0_LATERAL.Equals(csRcvPttnID) == true)
                {   // ポイント入力横入力端入力
                    csCell = csInputCellData[lLp].GetInterpolatedCell(0); // セル配列の0番目のセルを取得

                    dLateralQin[Dim0InLowerDim1[lLp]] += csCell.m_dData[lReadIdxQ];  //  Dim0InLowerDim1[lLp]には対応すべき 下位のセル番号が入っている

            }
            
            for (long lLp = 0; lLp <= m_csMyInf.NX; lLp++)
            {   // 
                dLateralQin[lLp] = dLateralQin[lLp] / m_csMyInf.WIDTH;
            }
       。。。。。。。。。。。。。。。。

        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            // 使用しやすいようにキャストしておく
            m_csMyInf = (MyKinematicLateralCalInfo)m_csCalInfo;

            // プロパティ設定
            MyKinematicWavePropertyData csPrptyInfo = csCellMdlPropertyInfo as MyKinematicWavePropertyData;
            if (csPrptyInfo != null)
            {
        。。。。。。。。。。。。。。。。。。。
        
                dLateralQin = new double[m_csMyInf.NX + 1];
        
。。。。。。。。。。。。。。。。。。。。



 上記モデルを使用して動作させた様子を下に示します。(5)、(24)、(42)番目のセル以後で、横入力以降により流量が急に増えています。
 (実際には、0相対値なので、グラフでは+1した値がセル番号になります。)
 

 




 A
 二番目の入力は 2次元の時系列情報を河道モデルの横から入力する場合です。 モデルとしては下図のように、2次元のGIS情報を生成するモデルから、2次元GIS情報メッシュ情報を受け取ります。  入力パターンのIDは MyExerciseModelDefine内に
        /// <summary>2次元入力横入力端入力</summary>
        public static readonly HySID IN_PATTERN_D2_LATERAL = new HySID("Dim2_Lateral_In");
として 定義しておきます。


       


 上流から取得された2次元情報はの一部が、下位モデルの7つのセルに入力されます。
 例えば、(3,2)番目の受信セルは、下位モデルの(5)番目に入力されます。
<?xml version="1.0" encoding="UTF-8"?>
<CellIDMngFile>
  <CellManageTable Kind="McModelCellCorrespondenceInf" FileName="ParameterData\D2SampleSideIn.xml">
    <TranCell IdxD1="0">
      <UpperModelCell IdxD1="3" IdxD2="2" />
      <LowerModelCell IdxD1="5" />
    </TranCell>
    <TranCell IdxD1="1">
      <UpperModelCell IdxD1="5" IdxD2="8" />
      <LowerModelCell IdxD1="12" />
    </TranCell>
    <TranCell IdxD1="2">
      <UpperModelCell IdxD1="10" IdxD2="14" />
      <LowerModelCell IdxD1="24" />
    </TranCell>
    <TranCell IdxD1="3">
      <UpperModelCell IdxD1="14" IdxD2="18" />
      <LowerModelCell IdxD1="28" />
    </TranCell>
    <TranCell IdxD1="4">
      <UpperModelCell IdxD1="22" IdxD2="21" />
      <LowerModelCell IdxD1="33" />
    </TranCell>
    <TranCell IdxD1="5">
      <UpperModelCell IdxD1="27" IdxD2="25" />
      <LowerModelCell IdxD1="38" />
    </TranCell>
    <TranCell IdxD1="6">
      <UpperModelCell IdxD1="32" IdxD2="27" />
      <LowerModelCell IdxD1="43" />
    </TranCell>
  </CellManageTable>
</CellIDMngFile>


 2次元の入力情報は1個のみとし、2つ以上の2次元入力はエラーとします。
 2次元入力に対応するコーディングは以下のようにします。

public class MyKinematicLateralModel : McForecastModelBase
{
       double[ ]  dLateralQin;  // 横入力一時保管(配列)
    //  二次元入力 接続セル数分確保する
        long   lIdxInfNumber;
        long[ ]  Dim2InUpperDim1;  // 上位受信データのセル配列1
        long[ ]  Dim2InUpperDim2;  // 上位受信データのセル配列2
        long[ ]  Dim2InLowerDim1;  // 下位側のセル番号


     。。。。。。。。。。。。。

    // モデルチェック時に 対応情報を格納しておく
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;

      。。。。。。。。。。。。

            McModelCellCorrespondenceInf csCellMng = null; // 上下要素モデル対応表
            McModelCellCorrespondenceInf.McCellIdxInf[] csCellIdx = null; // 具体的対応関係情報


            HySID csRcvPttnID;
            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。

                // 入力する伝送データの型式や設定値等をチェックし、一つでも期待情報でなければ、bRtn=false; を設定します。
                csRcvPttnID = csInputCellData[lLp].GetReceivePatternID();  // 受信パターン取得
                if (MyExerciseModelDefine.IN_PATTERN_TOP.Equals(csRcvPttnID) == true)
                {   // 上流入力の場合
                    // 何もしない
                }
                else if (MyExerciseModelDefine.IN_PATTERN_D2_LATERAL.Equals(csRcvPttnID) == true)
                {   // ポイント入力横入力端入力
                    csCellMng = csInputCellData[lLp].GetCellIDData() as McModelCellCorrespondenceInf;
                    if( csCellMng != null )
                    {   // 対応表ありならば
                        csCellIdx = csCellMng.GetCellIdxInf(ref lIdxInfNumber); // 接続セルを取得
                        
                        Dim2InUpperDim1 = new long[lIdxInfNumber];
                        Dim2InUpperDim2 = new long[lIdxInfNumber];
                        Dim2InLowerDim1 = new long[lIdxInfNumber];
                        for (long lI = 0; lI < lIdxInfNumber; lI++)
                        {   // 中継セル数分繰り返す
                            // 上位受信セルと下位モデルセルの対応番号を記憶する
                            Dim2InLowerDim1[lI] = csCellIdx[lI].m_lLowerModelCellIndexDim1;
                            Dim2InUpperDim1[lI] = csCellIdx[lI].m_lUpperModelCellIndexDim1;
                            Dim2InUpperDim2[lI] = csCellIdx[lI].m_lUpperModelCellIndexDim2;

                        }
                    }
                    else
                    {
                        csErrorInf.AddCheckErrorData(csInputCellData[lLp].GetUpperElementID(), MyExerciseModelDefine.MY_DYNAMIC_MODEL_KIND, "接続情報ファイルの設定がされていません。");
                        bRtn = false;
                    }
                }
        。。。。。。。。。。。。。。。。。


        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {

            for (long lLp = 0; lLp <= m_csMyInf.NX; lLp++)
            {   // 横入力値を0リセットする
                dLateralQin[lLp] = 0.0;
            }

            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {   // 入力する伝送データ数分繰り返します。
                csRcvPttnID = csInputCellData[lLp].GetReceivePatternID();  // 受信パターン取得
                csGetter = csInputCellData[lLp].GetCellDataGetter();  // 接続の対応表の取得
                lReadIdxQ = csGetter.GetIdx(0); // 実際に読む位置を取得(受信側は0番目が流量と認識している)

                if (MyExerciseModelDefine.IN_PATTERN_D0_LATERAL.Equals(csRcvPttnID) == true)
                {   // ポイント入力横入力端入力
                    csCell = csInputCellData[lLp].GetInterpolatedCell(0); // セル配列の0番目のセルを取得

                    dLateralQin[Dim0InLowerDim1[lLp]] += csCell.m_dData[lReadIdxQ];  //  Dim0InLowerDim1[lLp]には対応すべき 下位のセル番号が入っている

            }
            
            for (long lLp = 0; lLp <= m_csMyInf.NX; lLp++)
            {   // 
                dLateralQin[lLp] = dLateralQin[lLp] / m_csMyInf.WIDTH;
            }
       。。。。。。。。。。。。。。。。



        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            // 使用しやすいようにキャストしておく
            m_csMyInf = (MyKinematicLateralCalInfo)m_csCalInfo;

            // プロパティ設定
            MyKinematicWavePropertyData csPrptyInfo = csCellMdlPropertyInfo as MyKinematicWavePropertyData;
            if (csPrptyInfo != null)
            {
        。。。。。。。。。。。。。。。。。。。
        
                dLateralQin = new double[m_csMyInf.NX + 1];
        
。。。。。。。。。。。。。。。。。。。。



 上記モデルを使用して動作させた様子を下に示します。
 0相対値で、(5),(12),(24),(28),(33),(38),43)番目のセル以後で、横入力以降により流量が増えています。






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

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



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

初版:2013/09/12 |