// <summary>ソースコード：ＨＹＭＣＯ部分系制御クラス</summary>
// <author>CommonMP</author>

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

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Data.FileIO;
using CommonMP.HYMCO.CoreImpl.Controller;
using CommonMP.HYMCO.CoreImpl.Tool;
using CommonMP.HYMCO.CoreImpl.FigureUnity;

namespace CommonMP.HYMCO.CoreImpl.Model
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＭＣＯ部分系制御クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>
    /// [CommonMP][ver 1.0.0][2008/10/01][新規作成]
    /// [CommonMP][ver 1.3.0][2012/12/01][修正]
    /// [CommonMP][ver 1.4.0][2013/12/10][メソッド追加]
    /// </para>
    /// </remarks>
    public class McSubSystemCtl  : McGrElementCtl
    {
        /// <summary>ループ許容フラグ（非同期動作の時有効） </summary>
        bool m_bLoopPermissionFlg = false;

        /// <summary> 外部からの受信がある要素数 </summary>
        protected long m_lRecvElmNum = 0;
        /// <summary> 外部からの受信がある要素 </summary>
        protected McCalModel[] m_csRcvCalMdl;
        /// <summary> 外部からの受信接続 </summary>
        protected McTranInfo[] m_csRcvTranInfo;

        // Ver1.5 追加（計算に要した時間を表示）
        /// <summary> 現実の計算時間算出用</summary>
        protected HySTime m_csCalActualTime;
        
        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McSubSystemCtl csObj = new McSubSystemCtl( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McSubSystemCtl()
        {
            m_eDtFusionTiming = McDefine.DataFusionTiming.ASYNCHRONOUS; // 非同期をデフォルト化
        }

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

               
        /// <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 override bool IsAbleToCalculate(ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList, ref McStructErrorInfo csErrorInf)
        {
            bool bRtn = base.IsAbleToCalculate(ref csInputDataList, ref csOutputDataList, ref csErrorInf);

            bool bLocalRtn = true;
            //McStateCalTypeModel csStateCalModel=null; // 現状計算型モデルならば
            if (this.m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS)
            {   // 同期計算の場合
                m_csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < m_csElementList.Count; iLp++)
                {
                    m_csElementWork = m_csElmNode.Value;
                    if (m_csElementWork is McGrElement)
                    {   // Gr 化要素ならば
                        // Do Nothing
                    }
                    else
                    {
                        //csStateCalModel = m_csElementWork.GetCalModel() as McStateCalTypeModel;
                        //if( csStateCalModel != null )
                        //{
                        //}
                        if (m_csElementWork.GetDataFusionTiming() != this.m_eDtFusionTiming)
                        {
                           // ver1.5 エラートレース日本語対応
                            csErrorInf.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.ELEMENT_GROUP,
                                 Properties.HymcoImplResources.STATEMENT_MIS_TYPE_MODEL );
                           // csErrorInf.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "Missing type model (Cannot use in syncronous calculation)");
                            bLocalRtn = false;
                        }
                    }
                    m_csElmNode = m_csElmNode.Next;
                }
                //GetDataFusionTiming
            }

            this.CheckOutInCnnction(); // 外部入力を抽出
            
            if (bLocalRtn == false)
            {
                bRtn = false;
            }
            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>外部からの接続を抽出しメンバー変数に記憶する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>CheckOutInCnnction()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected virtual void CheckOutInCnnction()
        {
            //   接続編
            long lCnnctNum = m_csConnectionList.Count;  // 接続数
            //   先ずGr外からの流入接続がいくつあるかを調べる
            m_lRecvElmNum = 0;
            McConnection csCnnctWork = null;
            McInnerSndPort csRrySndPort = null;
            McGrElement csGrSendElm = null;
            LinkedListNode<McConnection> csCnnctNode = m_csConnectionList.First;
            for (long lLp = 0; lLp < lCnnctNum; lLp++)
            {
                csCnnctWork = csCnnctNode.Value;
                csRrySndPort = csCnnctWork.GetSendPort() as McInnerSndPort;
                if (csRrySndPort != null)
                {   // 中継送信端子
                    csGrSendElm = csRrySndPort.GetElement() as McGrElement;
                    if (csGrSendElm != null)
                    {   // Gr要素に接続
                        if (m_csElement.GetID().Equals(csGrSendElm.GetID()))
                        {   // 中継端子が自Gr(収束演算Gr)ならば
                            csCnnctNode = csCnnctNode.Next;
                            m_lRecvElmNum += 1;
                            continue; // 何もしない
                        }
                    }
                }
                csCnnctNode = csCnnctNode.Next;
            }
            // 外部からの受信がある要素 </summary>
            m_csRcvCalMdl = new McCalModel[m_lRecvElmNum];
            m_csRcvTranInfo = new McTranInfo[m_lRecvElmNum];
            long lRcvElmNo = 0;

            csCnnctNode = m_csConnectionList.First;
            for (long lLp = 0; lLp < lCnnctNum; lLp++)
            {
                csCnnctWork = csCnnctNode.Value;

                csRrySndPort = csCnnctWork.GetSendPort() as McInnerSndPort;
                if (csRrySndPort != null)
                {   // 中継送信端子
                    csGrSendElm = csRrySndPort.GetElement() as McGrElement;
                    if (csGrSendElm != null)
                    {   // Gr要素に接続
                        if (m_csElement.GetID().Equals(csGrSendElm.GetID()))
                        {   // 中継端子が自Gr(収束演算Gr)ならば
                            csCnnctNode = csCnnctNode.Next;
                            m_csRcvCalMdl[lRcvElmNo] = csCnnctWork.GetReceivePort().GetElement().GetCalModel();
                            m_csRcvTranInfo[lRcvElmNo] = csCnnctWork.GetTranInfo();
                            lRcvElmNo += 1;
                            continue; // 何もしない
                        }
                    }
                }
                csCnnctNode = csCnnctNode.Next;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>演算順序のチェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = CheckCalculationOrder( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns> long
        /// 正常時：McDefine.CALCULATION_NORMAL_RETURN
        /// 異常時：McDefine.CALCULATION_ABEND_RETURN_BECAUSE_OF_STRUCT_ERROR
        /// </returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 非同期演算の時有効
        /// 演算順序を上流から下流に並び替える。
        /// もし、ループ等があればエラーを返す
        /// </para>
        /// </remarks>
        public override long CheckCalculationOrder()
        {
            long lRtn = McDefine.CALCULATION_NORMAL_RETURN; // リターンコード
// start of 動作確認用
//m_csElmNode = m_csElementList.First;
//for (int iLp = 0; iLp < m_csElementList.Count; iLp++)
//{
//    m_csElementWork = m_csElmNode.Value;
//    McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "CheckCalculationOrder", "Elm is = " + m_csElementWork.GetID().ToString());
//    m_csElmNode = m_csElmNode.Next;
//}
// end of 動作確認用

            // ループ許容ならば　何もしない
            //if ( (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS && m_bLoopPermissionFlg == true) ||
            //      m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS )
            //{ return lRtn; }

            //　　　　 同期であっても、非同期であっても出来る限りの最適化を行っておく
            //if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS && m_bLoopPermissionFlg == false)
            //{   // 非同期通信ならば

                long lLclRtn = 0;// ローカル変数

                // 計算順序矯正完了状態保持用フラグのハッシュテーブル作成
                Hashtable OrderCorrectFlgTbl = new Hashtable();

                int iElmCnt = m_csElementList.Count;  // グループ内のエレメント数取得

                m_csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < iElmCnt; iLp++)
                {   // 個数分繰り返す
                    m_csElementWork = m_csElmNode.Value;    // エレメント取得
                    McGrElement csGrElementWork = m_csElementWork as McGrElement;
                    // 初期状態は全て　未矯正
                    OrderCorrectFlgTbl.Add(m_csElementWork, false);
                    m_csElmNode = m_csElmNode.Next;
                }

                List<McElement> csUpperElm = null;
                long lElementExchangeNum = 0;  // エレメント順序変更回数＝０
                bool bOrderCorrectFlg = false; // 矯正済みフラグ

                m_csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < iElmCnt; iLp++)
                {   // 個数分繰り返す
                    // 演算エレメント本体
                    m_csElementWork = m_csElmNode.Value;    // エレメント取得
                    McGrElement csGrElementWork = m_csElementWork as McGrElement;

                    //自分の前の要素について　IsConvergedFlgTblを参照し　false のものは　それを、計算順序リストの上で自分の直前に置く
                    // その後、iLp-=1 カウントを戻して m_csElmNode = m_csElmNode.Prev して   continue する
                    // lElementExchangeNum > iElmCntならば　接続に異常があると見なし計算を異常終了する
                    McCmnElement cmnElm = m_csElementWork as McCmnElement;
                    csUpperElm = cmnElm.GetUpperElementList();
                    bool bNotCorrectedElmExistFlg = false; // 未矯正の上位要素ありフラグ
                    for (int iEl = 0; iEl < csUpperElm.Count; iEl++)
                    {
                        bOrderCorrectFlg = (bool)OrderCorrectFlgTbl[csUpperElm[iEl]];
                        if (bOrderCorrectFlg == false)
                        {   // 上流に順序矯正していない要素があれば

                            m_csElementList.Remove(csUpperElm[iEl]);
                            // 収束していない要素を自分の前にもってくる
                            m_csElementList.AddBefore(m_csElmNode, csUpperElm[iEl]);
                            // 作業対象を自分の前の要素とする
                            m_csElmNode = m_csElmNode.Previous;
                            // 再度ループをまわす為ループカウンター数をデクリメントする
                            iLp -= 1;

                            lElementExchangeNum += 1;   // 入れ替え回数をインクリメント
                            bNotCorrectedElmExistFlg = true;
                            break;
                        }
                    }
                    if (bNotCorrectedElmExistFlg == true)
                    {   // 入れ替え発生したならば
                        if (lElementExchangeNum > iElmCnt)
                        {   // 入れ替え数が最大数よりも多くなれば接続上問題あり
                            lRtn = McDefine.CALCULATION_ABEND_RETURN_BECAUSE_OF_STRUCT_ERROR;
                           // ver1.5 エラートレース日本語対応
                            McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "CheckCalculationOrder",
                                Properties.HymcoImplResources.STATEMENT_CONNECT_STRUCT_NG );
                           // McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "CheckCalculationOrder", "Connection struct error");
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (csGrElementWork != null)
                    {   // Gr要素ならば
                        lLclRtn = csGrElementWork.CheckCalculationOrder(); // 内部の此処の要素に対して演算順序チェックを行わせる
                        if (lLclRtn != McDefine.CALCULATION_NORMAL_RETURN)
                        {
                            lRtn=McDefine.CALCULATION_ABEND_RETURN_BECAUSE_OF_STRUCT_ERROR;
                            break;
                        }
                    }
                    
                    OrderCorrectFlgTbl[m_csElementWork] = true; // 矯正した

                    // 次の演算要素取得
                    m_csElmNode = m_csElmNode.Next;
                } // end of for(要素数)

            //}   // end of 非同期

// start of 動作確認用
//m_csElmNode = m_csElementList.First;
//for (int iLp = 0; iLp < m_csElementList.Count; iLp++)
//{
//    m_csElementWork = m_csElmNode.Value;
//    McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "CheckCalculationOrder", "Elm is = " + m_csElementWork.GetID().ToString());
//    m_csElmNode = m_csElmNode.Next;
//}
// end of 動作確認用
            if (m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS || m_bLoopPermissionFlg == true)
            {   // 同期　あるいは、ループ許可ならば　「正常」として返す
                lRtn = McDefine.CALCULATION_NORMAL_RETURN;
            }
            return lRtn;
        }

        //=======================
        // 演算実行処理関連メソッド
        //=======================
        /// <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 override bool Initialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList)
        {
            ////**/
            if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
            {   // 非同期通信ならば
                // Do noting
            }
            else
            {
                int iElmCnt = m_csElementList.Count;  // グループ内のエレメント数取得

                m_csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < iElmCnt; iLp++)
                {   // 個数分繰り返す
                    m_csElementWork = m_csElmNode.Value;    // エレメント取得
                    // 現状計算型の同期演算対応） 
                    if (m_csElementWork.GetCalModel() as McStateCalModelBase != null)
                    {
                        m_csElementWork.GetCalModel().SetDeltaTime(this.m_csDltTime);
                        // 現状計算型のδTはサブシステムのδTに一致化させる
                    }
                    m_csElmNode = m_csElmNode.Next;
                }

            }
            // ↑　base.Initialize(。。。) の前に行うこと
            ////**/
            bool bRtn = base.Initialize(ref csInitialData,ref csInputDataList,ref csOutputDataList);
            return bRtn;
        }
        /// <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 override bool Calculable()
        {
            bool bRtn = true;

            if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
            {   // 非同期型ならば
                // 内部の要素モデルが計算するためには、外部からの入力が全てそろわないと計算できない。
                for (long lElmNo = 0; lElmNo < m_lRecvElmNum; lElmNo++)
                {
                    //if (m_csRcvCalMdl[lElmNo].Calculable() == false)
                    if (m_csRcvCalMdl[lElmNo].GetSimulationTime().After(m_csRcvTranInfo[lElmNo].GetLastTime()) == true)
                    {
                        bRtn = false;
                        break;
                    }
                }
            }
            return bRtn;
        }
        /// <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>収束演算要素の外から呼ばれるメソッド（Element.IsConverged() からコールされる）</para>
        /// </remarks>
        public override bool IsConverged()
        {
            bool bRtn = base.IsConverged();
            if (bRtn == false)
            {   // 内部に　要素モデルが存在し、そのモデルに直接外部から入力がある場合には、
                //  内部へのデータ入力がなければ計算できない
                if (this.Calculable() == false)
                {
                    bRtn = true;
                }
            }
            return bRtn;
        }
        /// <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 override long Calculate(ref HySDataLinkedList csInputDataList)
        {
            long lRtn = McDefine.CALCULATION_NORMAL_RETURN; // リターンコード
            long lLclRtn = 0;// ローカル変数
            HySTime csWorkTime = new HySTime(60.0); // ワーク変数（速度アップの為、ループ内での変数の new を控える
            int iElmCnt = m_csElementList.Count;  // グループ内のエレメント数取得
            int iLoop; // ループカウンター（速度アップのため、ループ内での変数のnew を控える）

            if (McGrElementCtl.RESTART_STATE != this.m_lStatus)
            {   // 再開段階でなければ
                this.m_lStatus = McGrElementCtl.CALCULATION_STATE; // 計算モード
            }

            // 1) 前準備として、csInputDataList の内容を　内部の要素に反映させる
            //      ↑ この処理は必要ない
            //long lInputDataNum = csInputDataList.GetRecordNum();
            //for (long lDtLp = 0; lDtLp < lInputDataNum; lDtLp++)
            //{
            //}


            // 2) グループ内部エレメントに計算実行
            // 2-1 再開／中断等のステータスにより　計算の取り掛かり値を設定
            if (McGrElementCtl.RESTART_STATE == this.m_lStatus)
            {   // 再開段階ならば
                //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", "m_lStatus = RESTART_STATE");
                // 再開時の演算要素を求める
                m_csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < m_iNodeItemNo; iLp++)
                {   // 個数分繰り返す
                    m_csElmNode = m_csElmNode.Next;
                }
                this.m_lStatus = McGrElementCtl.CALCULATION_STATE; // 計算モードへ移行
            }
            else
            {   // 再開段階ではなければ
                // 最初の要素から計算を進める
                m_csElmNode = m_csElementList.First;
                m_iNodeItemNo = 0;
            }
            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", " loop {Element.Calculate()} start");

            McGrElement csGrElementWork = null;
            HySTime csNextTargetTime = new HySTime(0); //  HySTime.DEFAULT_TIME.Clone(); <-- DEFAULT_TIME にする必要なし

            // 2-2 要素数分内部エレメントに計算を行わせる
            for (int iLp = m_iNodeItemNo; iLp < iElmCnt; iLp++)
            {   // 個数分繰り返す

                // 2-2-1 演算中断／終了時の処理
                if (McGrElementCtl.PAUSE_STATE == this.m_lStatus)
                {   // 計算中断モードならば　計算したところまでのノードを覚える
                    //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", "m_lStatus = PAUSE_STATE  break");
                    m_iNodeItemNo = iLp;
                    break;
                }
                else if (McGrElementCtl.STOP_STATE == this.m_lStatus)
                {   // 計算終了モードならば
                    //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", "m_lStatus = STOP_STATE  break");
                    break;
                }

                // 2-2-2 演算エレメント本体
                m_csElementWork = m_csElmNode.Value;    // エレメント取得
                csGrElementWork = m_csElementWork as McGrElement;

                // 2-2-3 各要素に演算時刻を設定する
                //m_csElementWork.SetTargetTime(m_csSimTime + m_csDltTime);
                // 次の演算目標時刻がシミュレーション終了時刻を越えないかどうか確認
                //csNextTargetTime = (m_csSimTime + m_csDltTime); // ＋オペレーターの使用は処理が遅くなる元
                csNextTargetTime.SetTime(m_csSimTime.GetTime() + m_csDltTime.GetTime());
                if (csGrElementWork == null && csNextTargetTime.Before(m_csFinalTgtTime) != true)
                {
                    // 単体要素で次の演算目標時刻がシミュレーション終了時刻を越えていれば
                    m_csElementWork.SetTargetTime(m_csFinalTgtTime);
                }
                else
                {
                    // Gr要素の場合は、終了時刻超過の確認はMcGrElementCtlで行われる
                    m_csElementWork.SetNextTargetTime(ref m_csSimTime, ref m_csDltTime);
                }

                // モノによっては、δTを変更する場合がある。
                //m_csElementWork.SetUpConvergenceInf(ref m_csConvergeCondInfo);

                // 2-2-4 一個の要素について演算を行う
                for (iLoop = 0; iLoop < 1000000; iLoop++)
                {   // 実質的∞：永遠に応答無しを防ぐ為、有限回に設定

                    // 2-2-4-1 個別要素の収束判別
                    if (m_csElementWork.IsConverged( ) == true)
                    {   // 収束していれば
                        //if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                        //{   // 非同期通信ならば
                        //    m_csElementWork.DataFusion();   // 演算結果公開（此処でDataFusionすると蓄積データ数はあまり大きくはならない）
                        //}
                        break;
                        // 次の要素の演算へ移行
                    }

                    // 2-2-4-2 個別要素の演算計算
                    lLclRtn = m_csElementWork.Calculate(); // 内部の此処の要素に対して計算を行わせる
                    if (lLclRtn != McDefine.CALCULATION_NORMAL_RETURN)
                    {   // エラー有りならば
                        lRtn = McDefine.CALCULATION_ABEND_RETURN;  // 全体の戻り値もエラー
                        // エラーログ等吐き出し
                        if (lLclRtn == McDefine.CALCULATION_FORCE_STOP_RETURN)
                        {   // 強制終了ならば
                           // ver1.5 エラートレース日本語対応
                            McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "Calculate", 
                                Properties.HymcoImplResources.STATEMENT_FORCE_STOP_CALC );
                           // McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), "McSubSystemCtl", "Calculate", "Force Stop Calculation");
                            lRtn = lLclRtn;
                            break;
                        }
                        else
                        {
                            McStructErrorInfo csErrorInfo = HySCommonInfoHash.GetCorrespondData(McDefine.CALCULATION_ERROR_INF, this.m_csElement.GetOwnerProjectID()) as McStructErrorInfo;
                            if (csErrorInfo != null)
                            {
                               // ver1.5 エラートレース日本語対応
                                csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                                        Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString() 
                                        + ".Calculate() :: " +Properties.HymcoImplResources.STATEMENT_RET_CODE + "("+lRtn.ToString() +")" );
                               // csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                               //         "Error return from " + m_csElementWork.GetCalModel().ToString() + ".Calculate() :: return_code(" + lRtn.ToString() + ")");
                            }
                           // ver1.5 エラートレース日本語対応
                            McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "Calculate", 
                                Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString()
                                + ".Calculate() ::" + Properties.HymcoImplResources.STATEMENT_RET_CODE + "(" + lRtn.ToString() + ")");
                           // McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "Calculate",
                           //     "Error return from " + m_csElementWork.GetCalModel().ToString() + ".Calculate() :: return_code(" + lRtn.ToString() + ")");

                            break;
                        }
                    }
                    // 2-2-4-3 個別要素の時刻を進める
                    m_csElementWork.GainSimulationTime(); // 要素内の時刻を進める

                    if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                    {   // 非同期通信ならば
                        lLclRtn = m_csElementWork.DataFusion();   // 演算結果公開(此処でDataFusionするとelementのδT が小さいときには非常に多くの情報が蓄積される)
                    }
                    else
                    {
                        // Ver1.3では下記コードを追加する（現状計算型の同期演算対応） 
                        if(m_csElementWork.GetCalModel() as McStateCalModelBase != null)
                        {
                            // 現状計算はGainSimulationTimeで時が進まないのでDataFusionを行い、要素自身の時刻を進める
                            lLclRtn = m_csElementWork.DataFusion();
                            //m_csElementWork.SetSimulationTime(m_csElementWork.GetCalModel().GetSimulationTime()+this.m_csDltTime);
                            //   ↑  現状計算型の時刻はサブシステムのシミュレーション時刻＋δTに一致化させる
                            //             ↑
                            //        既に現状型のδTをサブシステムのδTに一致化させているためこの処理は不要
                        }
                    }
                    if (lLclRtn != 0)
                    {
                        McStructErrorInfo csErrorInfo = HySCommonInfoHash.GetCorrespondData(McDefine.CALCULATION_ERROR_INF, this.m_csElement.GetOwnerProjectID()) as McStructErrorInfo;
                        if (csErrorInfo != null)
                        {
                           // ver1.5 エラートレース日本語対応
                            csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                                    Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString() 
                                    + ".DataFusion() :: " + Properties.HymcoImplResources.STATEMENT_RET_CODE + "(" + lLclRtn.ToString() + ")");
                           // csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                           //         "Error return from " + m_csElementWork.GetCalModel().ToString() + ".DataFusion() :: return_code(" + lLclRtn.ToString() + ")");
                        }
                       // ver1.5 エラートレース日本語対応
                        McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "DataFusion",
                            Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString()
                            + ".DataFusion() :: " + Properties.HymcoImplResources.STATEMENT_RET_CODE + "(" + lLclRtn.ToString() + ")");
                       // McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "DataFusion",
                       //     "Error return from " + m_csElementWork.GetCalModel().ToString() + ".DataFusion() :: return_code(" + lLclRtn.ToString() + ")");
                        lRtn = -1;
                        break;
                    }

                    //System.Threading.Thread.Sleep(0);   // スレッドの隙間を空けるため（スレッド関係の処理は非常に時間を消費する為、此処に入れるべきではない）
                }   // end of for(∞)

                if (lRtn == -1)
                {
                    break;
                }
                // 2-2-5 次の演算要素取得
                m_csElmNode = m_csElmNode.Next;

                //System.Threading.Thread.Sleep(0);   // スレッドの隙間を空けるため（スレッド関係の処理は非常に時間を消費する為、此処に入れるべきではない）
            } // end of for(要素数)


            //if (McGrElementCtl.PAUSE_STATE != this.m_lStatus)
            //{   // 計算中断モードではないならば
            //    m_iNodeItemNo = 0;
            //}

            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", " Element.DataFusion() start");
            if (m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS && lRtn == 0 )
            {   // 同期通信ならば
                // 2-3 内部エレメント同士ののデータ交換
                if (McGrElementCtl.CALCULATION_STATE == this.m_lStatus)
                {   // 計算モード中ならば
                    m_csElmNode = m_csElementList.First;
                    for (int iLp = m_iNodeItemNo; iLp < iElmCnt; iLp++)
                    {   // 個数分繰り返す
                        m_csElementWork = m_csElmNode.Value;    // エレメント取得

                        // Ver1.3（現状計算型の同期演算対応）  
                        if(m_csElementWork.GetCalModel() as McStateCalTypeModel != null)
                        {   // 現状計算型ならば
                            //  通常現状計算型は、DataFusion後、時計を進めるが、此の位置におけるDataFusionでは時計を進めない（既に時計は進んでいるため）
                            csWorkTime.SetTime( m_csElementWork.GetCalModel().GetSimulationTime().GetTime() ); // ｼﾐｭﾚｰﾀｰの現在時刻を一時保管
                            lLclRtn = m_csElementWork.DataFusion();
                            m_csElementWork.GetCalModel().SetSimulationTime(csWorkTime);
                            // 現状計算型ならば何もしない（上記個別要素のループ内で既にDataFusionを行う為） <-- ver1.3 で修正
                        }
                        else
                        {
                            // 現状計算型以外ならば
                            // 演算結果公開
                            lLclRtn = m_csElementWork.DataFusion();
                        }
                        if (lLclRtn != 0)
                        {   // 異常発生ならば
                            McStructErrorInfo csErrorInfo = HySCommonInfoHash.GetCorrespondData(McDefine.CALCULATION_ERROR_INF, this.m_csElement.GetOwnerProjectID()) as McStructErrorInfo;
                            if (csErrorInfo != null)
                            {
                               // ver1.5 エラートレース日本語対応
                                csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                                        Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString()
                                        + ".DataFusion() :: " + Properties.HymcoImplResources.STATEMENT_RET_CODE+ "(" + lLclRtn.ToString() + ")");
                               // csErrorInfo.AddSimuErrorData(m_csElementWork.GetID(), McModelLibraryDefine.HYM_MODEL_SUBSYSTEM,
                               //         "Error return from " + m_csElementWork.GetCalModel().ToString() + ".DataFusion() :: return_code(" + lLclRtn.ToString() + ")");
                            }
                           // ver1.5 エラートレース日本語対応
                            McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "DataFusion",
                                Properties.HymcoImplResources.STATEMENT_ERR_RETURN_FORM + m_csElementWork.GetCalModel().ToString()
                                + ".DataFusion() :: " + Properties.HymcoImplResources.STATEMENT_RET_CODE + "(" + lLclRtn.ToString() + ")");
                           // McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "DataFusion",
                           //     "Error return from " + m_csElementWork.GetCalModel().ToString() + ".DataFusion() :: return_code(" + lLclRtn.ToString() + ")");
                            lRtn = -1;
                            break;
                        }
                        m_csElmNode = m_csElmNode.Next;
                    } // end of for(要素数)
                }
            }

            // 2-4 グループ内の時刻を進める <-- これば外部で行う
            //m_csCalTime += m_csDltTime;
            //HySLog.LogOut(HySLog.SYSTEM_DEBUG, "McSubSystemCtl::Calculation", "end");
            return lRtn;
        }
        /*
        /// <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 override bool IsConverged()
        {   
            //bool bRtn = false; 速度アップのため、ローカル変数のnew を控える
            if (m_csSimTime.Before(m_csTgtTime) != true)
            {   // 計算時刻が、目標時刻を超えたならば
                return true;
            }
            return false;
        }
        */
        /// <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>無し</para>
        /// </remarks>
        public override void GainSimulationTime()
        {
            //m_csSimTime += m_csDltTime; 速度アップの為　＋＝演算子の使用は控える
            m_csSimTime.Add(m_csDltTime);
            m_csTotalPassingTime.SetTime(m_csSimTime.GetTime() - m_csStartTime.GetTime());
        }

        // Ver1.5 追加（計算に要した時間を表示）
        /// <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 override bool ReadyCalculation()
        {
            bool bRtn = base.ReadyCalculation();
            m_csCalActualTime = HySCalendar.CreateNowTime();   // 計算開始時刻
            return bRtn;
        }

        // Ver1.5 追加（計算に要した時間を表示）
        /// <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 override bool CompleteCalculation()
        {
            bool bRtn = base.CompleteCalculation();

            HySTime csEndTime = HySCalendar.CreateNowTime(); // 計算終了時刻
            // 計算に要した時間を計算
            csEndTime.SetTime(csEndTime.GetTime() - m_csCalActualTime.GetTime());
            double dTime = (double)((long)(csEndTime.GetTime() * 1000.0) );
            dTime = dTime / 1000.0;
            //String cslTime = HySCalendar.ToString(csEndTime, HySCalendar.FORMAT.lSW_WITH_SUB_SECOND);
            // ver1.5 エラートレース日本語対応
            string DispString = Properties.HymcoImplResources.STATEMENT_TIME_REQUIRD_COMPUTE + " "; // +dTime.ToString() + " [sec]";
            //string DispString = "計算に要した時間 ＝ "; // +dTime.ToString() + " [sec]";

            long lTime = (long)dTime;
            long lHH = (long)( dTime/3600.0 );
            long lMM = (long)((dTime - (double)(3600 * lHH)) / 60.0);
            long lSS = (long)((dTime - (double)(3600 * lHH + 60 * lMM)) / 1.0);
            long lmSec = (long)((dTime-(double)lTime)*1000.0);

            /***************************************************************
            注）秒以下の小数点についての仕様
　　　　　       ・小数点以下は最大３桁を表示します。例）1.012 [sec]
　　　　　       ・最後尾の０は省略します。          例）1.010 → 1.01 [sec]
　　　　　       ・小数点以下第一位は必ず表記します。例）1.0 [sec]
            ***************************************************************/
            string sMSec = lmSec.ToString("D3");

            if (sMSec.LastIndexOf('0') == 2)
            {
                sMSec = sMSec.Substring(0, 2);
            }
            if (sMSec.Length == 2 && sMSec.LastIndexOf('0') == 1)
            {
                sMSec = sMSec.Substring(0, 1);
            }

            if (lHH > 0)
            {
                DispString = DispString + lHH.ToString() + "[hr] " + lMM.ToString() + "[min] " + lSS.ToString() + "." + sMSec + "[sec]";
            }
            else if (lMM > 0)
            {
                DispString = DispString + lMM.ToString() + "[min] " + lSS.ToString() + "." + sMSec + "[sec]";
            }
            else if (lSS > 0)
            {
                DispString = DispString + lSS.ToString() + "." + sMSec + "[sec]";
            }
            else
            {
                DispString = DispString + lmSec.ToString() + "[msec]";
            }

            // 表示文字列作成　"Calculation elapsed time = "
            if (this.m_csElement is McFigureUnity)
            {   // 最上位の場合のみ計算に要した時間をログ出力する
                McLog.DebugOut(this.m_csSimTime, this.m_csElement.GetID(), McLog.SYSTEM, "CompleteCalculation", DispString);
            }
            return bRtn;
        }

        /// <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 override bool SetProperty(McPropertyInfoRoot csPropertyInfo)
        {
            McGroupPropertyInfo csInfo = csPropertyInfo as McGroupPropertyInfo;
            if (csInfo != null)
            {
                //m_elSolutionType=
                //m_bOwnDltTSetFlg=
                // ﾌﾛｰ制御情報設定
                m_eDtFusionTiming = csInfo.GetDataFusionTiming();
                //m_csElementList　のエレメント順番を設定する
                this.SetDataFusionTiming(m_eDtFusionTiming);

                // ループ許容フラグ設定
                if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                {
                    m_bLoopPermissionFlg = csInfo.GetLoopPermission();
                }
            }

            return true;
        }

        //★★★★★★★★★★★★★★★★★★★★★★★★★★★
        // 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 override bool SetProperty(McPropertyInfoRoot csPropertyInfo, ref McStructErrorInfo csErrorInfo)
        {
            McGroupPropertyInfo csInfo = csPropertyInfo as McGroupPropertyInfo;
            if (csInfo != null)
            {
                //m_elSolutionType=
                //m_bOwnDltTSetFlg=
                // ﾌﾛｰ制御情報設定
                m_eDtFusionTiming = csInfo.GetDataFusionTiming();
                //m_csElementList　のエレメント順番を設定する
                this.SetDataFusionTiming(m_eDtFusionTiming);

                // ループ許容フラグ設定
                if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                {
                    m_bLoopPermissionFlg = csInfo.GetLoopPermission();
                }
            }

            return true;
        }

        /// <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 override bool SetOnlineProperty(McPropertyInfoRoot csPropertyInfo)
        {
            //McGroupPropertyInfo csInfo = csPropertyInfo as McGroupPropertyInfo;

            //m_elSolutionType=
            //m_bOwnDltTSetFlg=
            // ﾌﾛｰ制御情報設定
            //m_eDtFusionTiming = csInfo.GetDataFusionTiming();
            //m_csElementList　のエレメント順番を設定する
            this.SetProperty(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 override bool OnlineInitialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList)
        {
            // Do Nothing
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルのユニーク種別を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySKind csKind = GetModelKind()</para>
        /// </example>
        /// <param name=""></param>
        /// <returns>モデルの種別を取得する</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override HySKind GetModelKind()
        {
            return McModelLibraryDefine.HYM_MODEL_SUBSYSTEM;
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイルにモデル内情報を全て書き出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileOUT(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileOUT(HySDataRoot csData)
        {
            if (csData == null || m_csElementList == null)
            {
                return false;
            }
            // 内部要素ごとに、計算状態保存処理を実行
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            bool bRtn = true;
            McCmnElementOutData csOutData = null;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                // データクラスの生成
                csOutData = m_csElementWork.CreateOutData();
                // 内部要素のFileOUT→要素演算モデルのFileOUT
                bRtn = m_csElementWork.FileOUT(csOutData);
                if (bRtn == false)
                {
                    return false;
                }

                //リストに追加
                ((McGrElementOutData)(csData)).AddCalElementOutData(csOutData);
                // インスタンスクリア
                csOutData = null;
                m_csElmNode = m_csElmNode.Next;
            }
           
            // 自メンバ変数の保存処理
            ((McGrElementOutData)(csData)).SetStatus(m_lStatus);
            ((McGrElementOutData)(csData)).SetNodeItemNo(m_iNodeItemNo);
            ((McGrElementOutData)(csData)).SetDltTSetFlg(m_bOwnDltTSetFlg);
            ((McGrElementOutData)(csData)).SetTimeData(McDefine.SIMULATION_TIME, m_csSimTime);
            ((McGrElementOutData)(csData)).SetTimeData(McDefine.START_TIME, m_csStartTime);
            ((McGrElementOutData)(csData)).SetTimeData(McDefine.PASSING_TIME, m_csTotalPassingTime);
            ((McGrElementOutData)(csData)).SetTimeData(McDefine.TARGET_TIME, m_csTgtTime);
            ((McGrElementOutData)(csData)).SetTimeData(McDefine.DELTA_TIME, m_csDltTime);

            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>ファイルからモデル情報を全て読み出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileIN(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileIN(HySDataRoot csData)
        {
            if (csData == null || m_csElementList == null)
            {
                return false;
            }
            // 内部要素ごとに、計算状態復元処理を実行
            // 復元データ数取得
            int iElmDataCnt = (int)((McGrElementOutData)(csData)).GetDataCount();
            // 要素・データリストのカーソルを先頭にセット
            m_csElmNode = m_csElementList.First;
            ((McGrElementOutData)(csData)).SetCursorFirst();
            bool bRtn = true;
            for (int iLp = 0; iLp < iElmDataCnt; iLp++)
            {
                if (m_csElmNode == null)
                {
                    //return false;
                    // ビルド後、全要素削除が行われ保存された場合正常とする
                    // モデル変更状態となるために再ビルドが走るため
                    break;
                }
                m_csElementWork = m_csElmNode.Value;

                // リストから取得
                McCmnElementOutData csCalElementOutData = ((McGrElementOutData)(csData)).GetCalElementOutData();
                HySID csElemID = (HySID)m_csElementWork.GetID();
                // ビルド後、要素の削除が行われ保存された場合、この段階で要素数と
                // 演算データ数の不一致が発生するため、要素IDで比較し整合をとる
                if (csElemID.Equals(csCalElementOutData.GetID()) == true)
                {
                    // 演算データが演算要素に対応したデータである
                    bRtn = m_csElementWork.FileIN(csCalElementOutData);
                    if (bRtn == false)
                    {
                        return false;
                    }
                    // インスタンスクリア
                    csCalElementOutData = null;
                    ((McGrElementOutData)(csData)).MoveCursorNext();
                    m_csElmNode = m_csElmNode.Next;

                    if (m_csElmNode == null)
                    {
                        // 内部要素に対し、計算状態復元処理を完了した
                        break;
                    }
                }
                else
                {
                    // 演算要素に対応したデータではない
                    ((McGrElementOutData)(csData)).MoveCursorNext();
                }

            }

            // 自メンバ変数の復元処理
            m_lStatus = ((McGrElementOutData)(csData)).GetStatus();
            m_iNodeItemNo = ((McGrElementOutData)(csData)).GetNodeItemNo();
            m_bOwnDltTSetFlg = ((McGrElementOutData)(csData)).GetDltTSetFlg();
            m_csSimTime = (HySTime)((McGrElementOutData)(csData)).GetTimeData(McDefine.SIMULATION_TIME);
            m_csStartTime = (HySTime)((McGrElementOutData)(csData)).GetTimeData(McDefine.START_TIME);
            m_csTotalPassingTime = (HySTime)((McGrElementOutData)(csData)).GetTimeData(McDefine.PASSING_TIME);
            m_csTgtTime = (HySTime)((McGrElementOutData)(csData)).GetTimeData(McDefine.TARGET_TIME);
            m_csDltTime = (HySTime)((McGrElementOutData)(csData)).GetTimeData(McDefine.DELTA_TIME);

            // 復元後の整合性確保
            if (m_csSimTime != null)
            {
                m_csSimTime.PostDeserialize();
            }
            if (m_csStartTime != null)
            {
                m_csStartTime.PostDeserialize();
            }
            if (m_csTotalPassingTime != null)
            {
                m_csTotalPassingTime.PostDeserialize();
            }
            if (m_csTgtTime != null)
            {
                m_csTgtTime.PostDeserialize();
            }
            if (m_csDltTime != null)
            {
                m_csDltTime.PostDeserialize();
            }


            return bRtn;
        }
    }
}
