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

6章 再び要素モデルの作成
6.2 色々な要素モデル
タンクモデル


 気象庁のホームページで公開されている 土壌雨量指数計算用の直列3段タンクモデル(Ishihara & Kobatake 1979)を、CommonMPの要素モデル化してみます。
 原理は 同ホームページを参照して下さい。(インターネット検索エンジンで キーワード ”タンクモデル” ”気象庁” ”土壌雨量指数”で検索して下さい。)
 

 要素モデルは、現在の降雨量から儺時間後の貯留量と流出量を計算するので、未来型の要素モデルとして制作します。
 制作する要素モデルは、雨量(mm/Hr)を入力し、その入力に応じて儺(10分)後の流出量量(m3/sec)と、貯留高を計算する仕様とします。
 第1タンクの流出孔の高さ:L1,L2 第2タンクの流出孔の高さ:L3, 第3タンクの流出孔の高さ:L4, 各流出孔の側面流出係数:α1,α2,α3,α4,及び、各タンクからの浸透流出孔の浸透係数:β1,β2,β3、及び、メッシュの大きさ(デフォルトは5Km)をプロパティ画面から設定できるようにします。 また、初期値として 各タンクの貯留高:S1,S2,S3、 書くタンクの側面流出量:Q1,Q2,Q3、を与えることができる事とします。 プロパティデータクラス、初期化データクラスはそれぞれ、CommonMPが提供する親クラス:McCellModelPropertyInfo、McInitialInfo を使用します。
 作成する要素モデルは、これまで演習用に作成してきたMyExerciseModelプロジェクトに追加します。
 
 要素モデルの制作手順を復習すると


<スタブ作成>
(1)型紙(MyHydraulicsModel、MyHydraulicsCalInfo)をコピーして要素モデルクラスと演算データクラスファイルを作成します。
(2)コピーして作成した2つのファイルを プロジェクトに追加します。
(3)追加した2つのファイルを開き namespace 名称を DLLの namespace 名に一致させます。
(4)要素モデルクラスと演算データクラスの名称を変更します。 
(5)ファクトリークラスの下記メソッドに 新しい要素モデルに関連するクラスのインスタンス生成処理を追加します。
  @CreateCalModel メソッド
  ACreateCalInfo メソッド
  BCreateModelProperty メソッド
  CCreateModelInitialInfo メソッド
  DGetCalModelInfoList メソッド

<演算データクラス内メソッドの実装>
(6)メンバー変数追加
(7)CopyInfo メソッド実装

<要素モデルクラス内メソッドの実装>
(8)プロパティ設定、チェックメソッドの実装
   @SetProperty メソッド
   AReceiveConnectionCheck、SendConnectionCheck メソッド
(9)初期化(Initialize) メソッドの実装
(10)計算に必要なメソッド実装
   @Calculate メソッド
   ADataFusion メソッド

 となります。

 モデルを作成する前に 必要なディファインを MyExerciseModelDefineクラス内に定義しておきます。
 

    public class MyExerciseModelDefine
    {
         。。。。。。。。。。。。。

        /// <summary>演習:TANKモデル種別</summary>
        public static readonly HySObjectKind MY_TANK_MODEL_KIND = new HySObjectKind("MyTANKModel");
        /// <summary>演習:Tankモデル名称</summary>
        public static readonly HySString MY_TANK_MODEL_NAME = new HySString("演習:Tankモデル");

        /// <summary>雨量入力 mm/Hr </summary>
        public static readonly HySID IN_PATTERN_RAIN = new HySID("RainIN");

 


 新しく作成するクラスは型紙クラスをコピーして作成します。
    MyHydraulicsModel.cs  → MyTankModel.cs
    MyHydraulicsCalInfo.cs → MyTankCalInfo.cs
 
 作成したソースをプロジェクトに追加し、ネームスペースとクラス名を変更します。
 
namespace CommonMP.HYMCO.OptionImpl.MyExerciseModelLIB
{
    public class MyTankModel : McForecastModelBase
    {
      

namespace CommonMP.HYMCO.OptionImpl.MyExerciseModelLIB
{
    public class MyTankCalInfo : McCalInfo
    {
      


  ファクトリークラス内の各メソッドに 関連するインスタンスを生成する処理を追加します。

    public class MyExerciseModelFactory : McBasicModelFactoryBase
    {
        public override McCalModel CreateCalModel(HySObjectKind csModelKind)
        {
        。。。。。。。
            else if (csModelKind.Equals(MyExerciseModelDefine.MY_TANK_MODEL_KIND) == true)
            {
                csCalModel = new MyTankModel();
            }
      。。。。。。。
        public override McCalInfo CreateCalInfo(HySObjectKind csModelKind)
        {
      。。。。。。。
            else if (csModelKind.Equals(MyExerciseModelDefine.MY_TANK_MODEL_KIND) == true)
            {
                csCalInfoData = new MyTankCalInfo();
            }
      。。。。。。。。
        public override McCellModelPropertyIF CreateModelProperty(HySID csLibraryID, HySObjectKind csModelKind)
        {
      。。。。。。。。
            else if (csModelKind.Equals(MyExerciseModelDefine.MY_TANK_MODEL_KIND) == true)
            {
                csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);
      。。。。。。。。
        public override McPropertyInfoRoot CreateModelInitialInfo(HySID csLibraryID, HySObjectKind csModelKind)
        {
      。。。。。。。。
            else if (csModelKind.Equals(MyExerciseModelDefine.MY_TANK_MODEL_KIND) == true)
            {
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
      。。。。。。。。。
        public override HySDataLinkedList GetCalModelInfoList()
        {
            McModelInfo csModelInfo=null;
      。。。。。。。。。
            csModelInfo = new McModelInfo(
                (HySID)this.GetFactoryID(),
                McModelLibraryDefine.DIVISION_CALCULATION_MODEL,    // <-- 演算モデルは、必ずこの値にして下さい
                new HySObjectKind("CAL_SAMPLE_MODELS"), // <-- LibraryCategoryXML.xmlに定義されている値を使用する
                MyExerciseModelDefine.MY_TANK_MODEL_KIND, // モデルの識別子
                MyExerciseModelDefine.MY_TANK_MODEL_NAME  // モデルの名称
                              );
            csModelInfo.SetVersionInf("Ver1.0 ");
            csModelInfo.SetSummaryInf("各種実験用 要素モデルです");
            csModelInfo.SetCreatorInf("要素モデル開発演習者");
            csModelInfo.SetIconName("Basin");

            m_csCalModelInforList.AddLast(csModelInfo); // 演算モデル情報の追加

  
 演算データクラス内にメンバー変数を追加し、メソッドの実装を行います。

    [Serializable]
    public class MyTankCalInfo : McCalInfo
    {
        public double dS1 = 0.0;
        public double dS2 = 0.0;
        public double dS3 = 0.0;
        public double dQ1 = 0.0;
        public double dQ2 = 0.0;
      。。。。。。
        public override bool CopyInfo(McCalInfo csOrgInfo)
        {
            MyTankCalInfo csOrdDt = csOrgInfo as MyTankCalInfo;
            if (csOrdDt != null)
            {
                dS1 = csOrdDt.dS1;
                dS2 = csOrdDt.dS2;
         。。。。。。。。

 要素モデルの各メソッドの実装を行います。 実装例の一部を示します。

     public class MyTankModel : McForecastModelBase
    {

        protected override bool Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = false;
            // 引数で与えられたデータを キャストしています。
            McInitialInfo csInDt = csInitialData as McInitialInfo;
            if (csInDt != null)
            {
                bRtn = true;

                csInDt.GetInfo("Q1", ref m_csMyInf.dQ1);
                csInDt.GetInfo("Q2", ref m_csMyInf.dQ2);
         。。。。。。。。
         。。。。。。。。

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

            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
                // 演算ステップ時刻設定
                this.m_csDltTime = new HySTime(csPrptyInfo.GetStepTime());

                csPrptyInfo.GetInfo("dL1", ref m_csMyInf.dL1);
                csPrptyInfo.GetInfo("dL2", ref m_csMyInf.dL2);
                csPrptyInfo.GetInfo("dL3", ref m_csMyInf.dL3);
          。。。。。。。。
          。。。。。。。。

        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            HySCellData csRcvCellData = null;
            double dRIn = 0.0;

            for (long lLp = 0; lLp < lInputDataNum; lLp++)
            {
                //  ポイント時系列伝送データを取得します。
                csRcvCellData = csInputCellData[lLp].GetInterpolatedCell(0);

                //  セル内の0番目の情報を取得します
                dRIn += csInputCellData[lLp].Data(csRcvCellData, 0);
            }
            
            double dltT = this.m_csDltTime.GetTime()/3600.0;  // δTを時間単位で取得する
           
            //q1(t)=α1{S1(t)−L1}+α2{S1(t)−L2}
            double dQ101 = m_csMyInf.dA1 * (m_csMyInf.dS1 - m_csMyInf.dL1);
            if (dQ101 < 0.0) { dQ101 = 0.0; }
            double dQ102 = m_csMyInf.dA2 * (m_csMyInf.dS2 - m_csMyInf.dL2);
            if (dQ102 < 0.0) { dQ102 = 0.0; }
            m_csMyInf.dQ1 = dQ101 + dQ102;


            //q2(t)=α3{S2(t)−L3}
            m_csMyInf.dQ2 = m_csMyInf.dA3 * (m_csMyInf.dS2 - m_csMyInf.dL3);
            if (m_csMyInf.dQ2 < 0.0) { m_csMyInf.dQ2 = 0.0; }

            //q3(t)=α4{S3(t)−L4}
            m_csMyInf.dQ3 = m_csMyInf.dA4 * (m_csMyInf.dS3 - m_csMyInf.dL4);
            if (m_csMyInf.dQ3 < 0.0) { m_csMyInf.dQ3 = 0.0; }

            //S1(t+Δt)=(1-β1Δt)・S1(t)−q1(t)・Δt+R
            m_csMyInf.dS1 = (1.0 - m_csMyInf.dB1 * dltT) * m_csMyInf.dS1 - m_csMyInf.dQ1 * dltT + dRIn;

            //S2(t+Δt)=(1-β2Δt)・S2(t)−q2(t)・Δt+β1・S1(t)・Δt
            m_csMyInf.dS2 = (1.0 - m_csMyInf.dB2 * dltT) * m_csMyInf.dS2 - m_csMyInf.dQ2 * dltT + m_csMyInf.dB1 * m_csMyInf.dS1 * dltT;

            //S3(t+Δt)=(1-β3Δt)・S3(t)−q3(t)・Δt+β2・S2(t)・Δt
            m_csMyInf.dS3 = (1.0 - m_csMyInf.dB3 * dltT) * m_csMyInf.dS3 - m_csMyInf.dQ3 * dltT + m_csMyInf.dB2 * m_csMyInf.dS2 * dltT;

            return 0;
        }


 実装を完了したならば、ディバッグモードで立ち上げ、動作を確認します。

 


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

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



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

初版:2013/08/13 |