// <summary>ソースコード：演算モデルの必須共通処理クラス</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;

using CommonMP.HYSSOP.CoreImpl;
using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Controller;


namespace CommonMP.HYMCO.Interface.Model
{
    /// <summary><para>class outline:</para>
    /// <para>演算モデルの必須共通処理クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// <para>[CommonMP][ver 1.3.0][2012/12/01][メソッド追加]</para>
    /// <para>[CommonMP][ver 1.4.0][2013/12/10][メソッド追加]</para>
    /// </remarks>
    public abstract class McCalModelEssential : McCalModel
    {
        /// <summary>要素モデルが属しているシミュレータのID</summary>
        protected HySIdentifier m_csSimulationID = null;

        /// <summary>自らを保持している要素</summary>
        protected McElement m_csElement=null;

        // === 時刻関連 ===
        /// <summary>演算時刻（シミュレーション内の現在時刻）</summary>
        protected HySTime m_csSimTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>目標時刻（当面の目標時刻）</summary>
        protected HySTime m_csTgtTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>刻み時間（δT)</summary>
        protected HySTime m_csDltTime = new HySTime(999999999,0,0,0);

        // === 入出力（前後に接続された要素モデル間伝送データ）
        /// <summary> 入力（受信）情報数 </summary>
        protected long m_lInputDataNum = 0;
        /// <summary> 入力（受信）情報 </summary>
        protected McTranInfo[] m_csInputData;
        /// <summary> 出力（送信）情報数 </summary>
        protected long m_lOutputDataNum = 0;
        /// <summary> 出力（送信）情報 </summary>
        protected McTranInfo[] m_csOutputData;

        /*
        //// <summary>入力情報内挿方法式 </summary>
        //protected HySDefine.InterpolateType m_eInterpolateType = HySDefine.InterpolateType.NO_INTERPOLATE;

        /// <summary> 入力情報内挿ツール </summary>
        protected HySInterpolatorIF[] m_csInterpolator=null;
        /// <summary> 入力情報セル内データ取得用インデックス情報 </summary>
        protected HySCellDataGetter[] m_csCellDataGetter = null;
        /// <summary>入力接続情報管理 </summary>
        protected McReceiveCellDataMngIF m_csInputCellDataGetterMng = null;
        */
        /// <summary> DataFusion()発行のタイミング（演算フロー制御）
        /// （同期：全ての要素が演算終了後DataFutionを行う／非同期：要素が演算終了後個別にDataFutionを行う） </summary>
        protected McDefine.DataFusionTiming m_eDtFusionTiming = McDefine.DataFusionTiming.ASYNCHRONOUS;

        /// <summary>演算時刻保存</summary>
        protected HySTime m_csMemorySimTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>演算経過時刻保存</summary>
        protected HySTime m_csMemoryTotalPassingTime = new HySTime(0);

        //=========================
        // 演算実行前処理関連メソッド
        //=========================




        /// <summary><para>method outline:</para>
        /// <para>モデル演算可能かをチェックする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = IsAbleToCalculate(ref csInputDataList, ref csOutputDataList, ref csErrorInf)</para>
        /// </example>
        /// <param name="csInputDataList">前段接続要素からの伝送情報リスト</param>
        /// <param name="csOutputDataList">前段接続要素への伝送情報リスト</param>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:演算可能、=false:演算不能</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool IsAbleToCalculate(ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList, ref McStructErrorInfo csErrorInf);

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csInputDataList, ref csErrorInf)</para>
        /// </example>
        /// <param name="csInputDataList">入力情報リスト</param>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        public virtual bool ReceiveConnectionCheck(ref HySDataLinkedList csInputDataList, ref McStructErrorInfo csErrorInf)
        {
            // 入力情報の配列化
            m_lInputDataNum = csInputDataList.GetCount();
            m_csInputData = new McTranInfo[m_lInputDataNum];

            /* 下記は、今後変更発生時の参考のため、コメントとして残しておく
            HySTimeSeriesBase csTmSrsDt = null; // 時系列データ
            McTranInfoIFCellType csCellDt = null; // セル型データ
            HySCellDataGetter csInputCellGetter = null; // セル内インデックス管理クラス
            
            m_csInterpolator = new HySInterpolatorIF[m_lInputDataNum];
            m_csCellDataGetter = new HySCellDataGetter[m_lInputDataNum];
            */

            csInputDataList.SetCursorFirst();
            for (long lP = 0; lP < m_lInputDataNum; lP++)
            {   // 入力データ数分
                m_csInputData[lP] = csInputDataList.GetCursorData() as McTranInfo;

                /* 下記は、今後変更発生時の参考のため、コメントとして残しておく
                // 時系列情報か否か？
                csTmSrsDt = m_csInputData[lP] as HySTimeSeriesBase;
                if (csTmSrsDt != null)
                {   // 時系列データが入力ならば　内挿処理ツールを生成する
                    m_csInterpolator[lP] = HySInterpolatorFactory.CreateInterpolator(m_eInterpolateType);
                    m_csInterpolator[lP].SetTimeSeriesData(csTmSrsDt);
                }
                else
                {   // 時系列データでなければ　内挿処理は不用
                    m_csInterpolator[lP] = null;
                }
                // セル型情報か否か？
                csCellDt = m_csInputData[lP] as McTranInfoIFCellType;
                if (csCellDt != null)
                {   // セル型情報が入力ならば　入力情報セル内データ取得用クラスを設定
                    csInputCellGetter = null;
                    if (m_csInputCellDataGetterMng != null)
                    {
                        csInputCellGetter = m_csInputCellDataGetterMng.GetCellDataGetter(m_csInputData[lP].GetConnectionID());
                    }

                    if( csInputCellGetter != null )
                    {   //(入力情報変換セルがあるならば)
                        m_csCellDataGetter[lP] = csInputCellGetter;
                    }
                    else
                    {
                        m_csCellDataGetter[lP] = new HySCellDataGetter(csCellDt.GetDataDimentionInCell());  // この部分本当に良いか？　モデル側の期待入力セルに合わせるべき
                        // デフォルト取得とする
                    }
                }
                else
                {   // セル型情報でなければ　入力情報セル内データ取得用インデックス情報は不用
                    m_csCellDataGetter[lP] = null;
                }
                */


                csInputDataList.MoveCursorNext();
            }

            return this.ReceiveConnectionCheck(ref csErrorInf);
        }
        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected abstract bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf);
        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SendConnectionCheck(ref csOutputDataList, ref csErrorInf)</para>
        /// </example>
        /// <param name="csOutputDataList">出力情報リスト</param>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        public virtual bool SendConnectionCheck(ref HySDataLinkedList csOutputDataList, ref McStructErrorInfo csErrorInf)
        {
            // 出力情報の配列化
            m_lOutputDataNum = csOutputDataList.GetCount();
            m_csOutputData = new McTranInfo[m_lOutputDataNum];
            csOutputDataList.SetCursorFirst();
            for (long lP = 0; lP < m_lOutputDataNum; lP++)
            {   // 出力データ数分
                m_csOutputData[lP] = csOutputDataList.GetCursorData() as McTranInfo;
                csOutputDataList.MoveCursorNext();
            }
            return this.SendConnectionCheck(ref csErrorInf);
        }
        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SendConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected abstract bool SendConnectionCheck(ref McStructErrorInfo csErrorInf);

        //=======================
        // 演算実行処理関連メソッド
        //=======================
        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(ref csInitialData, ref csInputDataList, ref csOutputDataList)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="csInputDataList">前段接続要素からの伝送情報リスト</param>
        /// <param name="csOutputDataList">前段接続要素への伝送情報リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool Initialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList)
        {
            bool bRtn = this.Initialize(ref csInitialData);
            if (bRtn == true)
            {
                this.DataFusion(ref csOutputDataList);
            }
            return bRtn;
        }
        /*
        /// <summary><para>method outline:</para>
        /// <para>接続線のみ初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>InputConnectionInitialize(ref csInitialData, ref csInputDataList)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="csInputDataList">前段接続要素からの伝送情報リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Initialize()はモデル内部まで初期化するが、本メソッドはモデルに接続されている接続線情報を初期化する</para>
        /// </remarks>
        public abstract bool InputConnectionInitialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList);
        **/

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected abstract bool Initialize(ref McPropertyInfoRoot csInitialData);

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate(ref csInputDataList)</para>
        /// </example>
        /// <param name="csInputDataList">演算に必要な入力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract long Calculate(ref HySDataLinkedList csInputDataList);

        /// <summary><para>method outline:</para>
        /// <para>モデル演算可能判別</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = Calculable()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=true:計算可 =false:計算不可</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool Calculable()
        {
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>モデル演算における収束判別</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = IsConverged( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=true:収束完了 =false:未収束</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool IsConverged();
        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion(ref csOutputDataList)</para>
        /// </example>
        /// <param name="csOutputDataList">演算結果を公開する出力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract long DataFusion(ref HySDataLinkedList csOutputDataList);

        /// <summary><para>method outline:</para>
        /// <para>計算開始時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = ReadyCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算開始の　最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public abstract bool ReadyCalculation();
        /// <summary><para>method outline:</para>
        /// <para>計算終了時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CompleteCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算終了時　最後の最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public abstract bool CompleteCalculation();

        /// <summary><para>method outline:</para>
        /// <para>計算中断時に動作する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SuspendCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算中断時　最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public abstract bool SuspendCalculation();

        /// <summary><para>method outline:</para>
        /// <para>シミュレーションデータコンテナの内容を設定する処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimDataContainerInfo( csDataContainer )</para>
        /// </example>
        /// <param name="csDataContainer">シミュレーションデータコンテナ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract void SetSimDataContainer(HySSimulationDataContainer csDataContainer);

        /// <summary><para>method outline:</para>
        /// <para>モデル内部の時刻を進める</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GainSimulationTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void GainSimulationTime();
        /// <summary><para>method outline:</para>
        /// <para>演算済みのシミュレーション時刻を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySTime csSimuTime = GetCalDoneTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySTime 演算済みのシミュレーション時刻</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算済みのシミュレーション時刻と内部のシミュレーション時刻が一致しないモデルの場合に必要</para>
        /// </remarks>
        public abstract HySTime GetCalDoneTime();
        /// <summary><para>method outline:</para>
        /// <para>演算用刻み時間を自動的に変更する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ChangeDeltaTimeAutomatically()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void ChangeDeltaTimeAutomatically();

        /// <summary><para>method outline:</para>
        /// <para>演算実行中断中のプロパティ等情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SetOnlineProperty(csPropertyInfo)</para>
        /// </example>
        /// <param name="csPropertyInfo">プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算中断中にプロパティ、初期値等を変更して動作させ場合等に使用する(将来拡張用)</para>
        /// </remarks>
        public virtual bool SetOnlineProperty(McPropertyInfoRoot csPropertyInfo)
        {
            return true;
        }
        /// <summary><para>method outline:</para>
        /// <para>演算実行中断中のモデルを初期化</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(ref csInitialData, ref csInputDataList, ref csOutputDataList)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="csInputDataList">前段接続要素からの伝送情報リスト</param>
        /// <param name="csOutputDataList">前段接続要素への伝送情報リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算中断中にプロパティ、初期値等を変更して動作させ場合等に使用する(将来拡張用)</para>
        /// </remarks>
        public virtual bool OnlineInitialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList)
        {
            return true;
        }
 
        //================
        // 各種設定メソッド
        //================

        /// <summary><para>method outline:</para>
        /// <para>シミュレーションIDを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimulationID(csSimulationID)</para>
        /// </example>
        /// <param name="csSimulationID">シミュレーションID</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSimulationID(HySIdentifier csSimulationID)
        {
            m_csSimulationID = csSimulationID;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCalInfo(csCalInfo)</para>
        /// </example>
        /// <param name="csCalInfo">演算結果格納するクラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void SetCalInfo(McCalInfo csCalInfo);
        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCalInfo csCalInfo = GetCalInfo()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>モデル演算中の情報格納クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract McCalInfo GetCalInfo();
        /// <summary><para>method outline:</para>
        /// <para>演算時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimulationTime(csCalTime)</para>
        /// </example>
        /// <param name="csCalTime">演算時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void SetSimulationTime(HySTime csCalTime);
        /// <summary><para>method outline:</para>
        /// <para>演算時刻を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySTime csSimuTime = GetSimulationTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算時刻</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract HySTime GetSimulationTime();
        /// <summary><para>method outline:</para>
        /// <para>演算開始時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetStartTime(csStartTime)</para>
        /// </example>
        /// <param name="csStartTime">演算開始時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract void SetStartTime(HySTime csStartTime);
        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetTargetTime(csTgtTime)</para>
        /// </example>
        /// <param name="csTgtTime">目標時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void SetTargetTime(HySTime csTgtTime);
        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySTime csTgtT = GetTargetTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算目標時刻</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract HySTime GetTargetTime();
        /// <summary><para>method outline:</para>
        /// <para>演算中に次の演算目標時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetNextTargetTime(ref csCalTime,ref csDltTime)</para>
        /// </example>
        /// <param name="csCalTime">現在時刻</param>
        /// <param name="csDltTime">増加時間</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract void SetNextTargetTime(ref HySTime csCalTime, ref HySTime csDltTime);
        /// <summary><para>method outline:</para>
        /// <para>演算刻み時間を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetDeltaTime(csDltTime)</para>
        /// </example>
        /// <param name="csDltTime">演算刻み時間</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public abstract void SetDeltaTime(HySTime csDltTime);
        /// <summary><para>method outline:</para>
        /// <para>演算刻み時間を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySTime csDtlT = GetDeltaTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>演算刻み時間</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract HySTime GetDeltaTime();

        /// <summary><para>method outline:</para>
        /// <para>最終目標時間設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimuGoalTime( csTm )</para>
        /// </example>
        /// <param name="csTm">最終目標時間</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetSimuGoalTime(HySTime csTm)
        {
            // Do Nothing
        }

        /// <summary><para>method outline:</para>
        /// <para>解法を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSolutionType(elType)</para>
        /// </example>
        /// <param name="elType">解法（通常計算／収束計算）</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract void SetSolutionType(McDefine.SolutionType elType);
        /// <summary><para>method outline:</para>
        /// <para>モデルの解法を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDefine.SolutionType eType = GetSolutionType()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>解法（McCalculateModelBase.NORMAL_TYPE/CONVERGENCE_TYPE）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract McDefine.SolutionType GetSolutionType();

        /// <summary><para>method outline:</para>
        /// <para>DataFusion()発行のタイミング（演算フロー制御）設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetDataFusionTiming(eDtFusionTiming)</para>
        /// </example>
        /// <param name="eDtFusionTiming"> 同期／非同期
        /// McDefine.DataFusionTiming.SYNCHRONOUS：全ての要素が演算終了後DataFutionを行う
        /// McDefine.DataFusionTiming.ASYNCHRONOUS：非同期：要素が演算終了後個別にDataFutionを行う）
        /// </param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetDataFusionTiming(McDefine.DataFusionTiming eDtFusionTiming)
        {
            m_eDtFusionTiming = eDtFusionTiming;
        }
        /// <summary><para>method outline:</para>
        /// <para>DataFusion()発行のタイミング（演算フロー制御）取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDefine.DataFusionTiming eTm = GetDataFusionTiming()</para>
        /// </example>
        /// <param name=""> 無し</param>
        /// <returns>同期／非同期</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McDefine.DataFusionTiming GetDataFusionTiming()
        {
            return m_eDtFusionTiming;
        }
        //====================
        // その他必要なメソッド
        //====================

        /// <summary><para>method outline:</para>
        /// <para>エレメントインスタンスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetElement(csElement)</para>
        /// </example>
        /// <param name="csElement">自モデルを保持するエレメント</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetElement(McElement csElement)
        {
            m_csElement = csElement;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算状態復元のためのデータクラスを生成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCmnElementOutData csElementOutData = CreateOutData()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>データクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract McCmnElementOutData CreateOutData();

        /// <summary><para>method outline:</para>
        /// <para>ファイルにモデル内情報を全て書き出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileOUT(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool FileOUT(HySDataRoot csData);
        /// <summary><para>method outline:</para>
        /// <para>ファイルからモデル情報を全て読み出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileIN(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool FileIN(HySDataRoot csData);

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csPropertyInfo)</para>
        /// </example>
        /// <param name="csPropertyInfo">プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool SetProperty(McPropertyInfoRoot csPropertyInfo);

        //★★★★★★★★★★★★★★★★★★★★★★★★★★★
        // Ver1.4で追加(プロパティ情報設定時のメッセージスロー)
        //★★★★★★★★★★★★★★★★★★★★★★★★★★★
        /// <summary><para>method outline:</para>
        /// <para>モデル構築時にプロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csPropertyInfo, ref csErrorInfo)</para>
        /// </example>
        /// <param name="csPropertyInfo">プロパティ情報</param>
        /// <param name="csErrorInfo">エラー情報</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public abstract bool SetProperty(McPropertyInfoRoot csPropertyInfo, ref McStructErrorInfo csErrorInfo);
      
        /// <summary><para>method outline:</para>
        /// <para>要素識別子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySIdentifier csID = GetID( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>識別子</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual HySIdentifier GetID()
        {
            return m_csElement.GetID();
        }

        /// <summary><para>method outline:</para>
        /// <para>現在状態の一時記憶（但し計算途中状態は除く）</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Memorize() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public abstract void Memorize();
        /// <summary><para>method outline:</para>
        /// <para>Memorize()した情報の復元</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Remember() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public abstract void Remember();

        // Ver1.3 
        /// <summary><para>method outline:</para>
        /// <para>収束計算に必要な初期出力を強制的に行わせる</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = InitialDataFusionForConvergentCalculation(dErrorVal)</para>
        /// </example>
        /// <param name="dErrorVal">出力の目安を示す値</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual long InitialDataFusionForConvergentCalculation(double dErrorVal)
        {
            // 派生クラスにて必要に応じオーバーライドして実装のこと
            return 0;
        }


        // ===============================
        // 共通便利ツール
        // ===============================
        /// <summary><para>method outline:</para>
        /// <para>CommonMPデータホームディレクトリ取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csDataHomeDirectory = GetDataHomeDirectory()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySString  CommonMPデータホームディレクトリ</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual HySString GetDataHomeDirectory()
        {
            return HySEnvInf.GetDataHomeDirectory();
        }
        /// <summary><para>method outline:</para>
        /// <para>プロジェクトグループ名称取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csGrpName = GetProjectGroupName()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySString  プロジェクトグループ名称</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual HySString GetProjectGroupName()
        {
            string  sPrjName = "";
            HySCommonInfoHash.GetCorrespond(McDefine.PROJECT_GROUP_NAME, this.m_csElement.GetOwnerProjectID(), ref sPrjName); 
            return new HySString(sPrjName);
        }
        /// <summary><para>method outline:</para>
        /// <para>プロジェクトグループディレクトリ取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csDirectory = GetProjectGroupDirectory()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySString  プロジェクトグループディレクトリ</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual HySString GetProjectGroupDirectory()
        {
            return (HySEnvInf.GetDataHomeDirectory() + new HySString("\\") + this.GetProjectGroupName());
        }
        /// <summary><para>method outline:</para>
        /// <para>計算の識別子（計算ロット）を取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySString csCalLot = GetCalculationLotName()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySString  計算の識別子（計算ロット）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>同じプロジェクトで計算を繰り返す場合、前回の計算と今回の計算を区別するための識別子を取得する</para>
        /// </remarks>
        public virtual HySString GetCalculationLotName()
        {
            string sLotName = "";
            HySCommonInfoHash.GetCorrespond(McDefine.CALCULATION_LOT_NAME, this.m_csElement.GetOwnerProjectID(), ref sLotName);
            return new HySString(sLotName);
        }
        /// <summary><para>method outline:</para>
        /// <para>データホームを基準とした相対パスを取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetRelativePathBasedOnDataHome(csAbsolutePath, refcsRelativePath)</para>
        /// </example>
        /// <param name="csAbsolutePath">絶対パス</param>
        /// <param name="csRelativePath">相対パス</param>
        /// <returns>相対化不能の場合には　false を返す</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>与えられた絶対パス値を　CommonMPデータホームを基準とした相対パスに変換して取得する</para>
        /// </remarks>
        public virtual bool GetRelativePathBasedOnDataHome(HySString csAbsolutePath, ref HySString csRelativePath)
        {
            string sRelativePath = "";
            bool bRtn = HySCommonInfoHash.DirectoryPathExchange(
                this.GetDataHomeDirectory().ToString(),
                csAbsolutePath.ToString(),
                ref sRelativePath);
            csRelativePath.SetChar(sRelativePath);
            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>プロジェクトグループディレクトリを基準とした相対パスを取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = GetRelativePathBasedOnProjectGroup(csAbsolutePath, refcsRelativePath)</para>
        /// </example>
        /// <param name="csAbsolutePath">絶対パス</param>
        /// <param name="csRelativePath">相対パス</param>
        /// <returns>相対化不能の場合には　false を返す</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>与えられた絶対パス値を　プロジェクトグループディレクトリを基準とした相対パスに変換して取得する</para>
        /// </remarks>
        public virtual bool GetRelativePathBasedOnProjectGroup(HySString csAbsolutePath, ref HySString csRelativePath)
        {
            string sRelativePath = "";
            bool bRtn = HySCommonInfoHash.DirectoryPathExchange(
                this.GetDataHomeDirectory().ToString() + "\\" + this.GetProjectGroupName().ToString(),
                csAbsolutePath.ToString(),
                ref sRelativePath);
            csRelativePath.SetChar(sRelativePath);
            return bRtn;
        }

    }
}
