// <summary>ソースコード：ＨＹＭＣＯグループ化要素制御クラス</summary>
// <author>CommonMP</author>

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.CoreImpl.Controller;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Data.StructInfo;


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

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 abstract class McGrElementCtl : McCalModel
    {
        /// <summary>自らを保持している要素</summary>
        protected McElement m_csElement=null;
        /// <summary>解法</summary>
        McDefine.SolutionType m_elSolutionType = McDefine.SolutionType.NORMAL_TYPE;

        /// <summary>内部要素リスト（演算操作用：演算スレッドから内部のエレメントを制御する）</summary>
        protected LinkedList<McElement> m_csElementList=null;
        /// <summary>
        /// 内部要素リスト（指示伝達用：演算スレッド以外から内部のエレメントを制御する）
        /// 　演算実行中に、他のスレッドが、m_csElementList を操作すると、演算制御不能となる為　別リストで同じエレメントを管理する
        /// </summary>
        protected LinkedList<McElement> m_csElementListForCommand=null;

        /// <summary>計算中のノード順番号</summary>
        protected int m_iNodeItemNo = 0;

        /// <summary>送信端子リスト</summary>
        protected List<McSendPort> m_csSendPortList=null; 

        /// <summary>演算時刻</summary>
        protected HySTime m_csSimTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>開始時刻</summary>
        protected HySTime m_csStartTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>演算経過時刻</summary>
        protected HySTime m_csTotalPassingTime = new HySTime(0);
        /// <summary>目標時刻</summary>
        protected HySTime m_csTgtTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>刻み時間</summary>
        protected HySTime m_csDltTime = new HySTime(60.0);
        /// <summary>最終目標時刻(シミュレータ終了時刻)</summary>
        protected HySTime m_csFinalTgtTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>目標時刻がシミュレータ終了時刻を超過したか判定するフラグ : trueは超過</summary>
        protected bool m_bExceedGoalTimeFlg = false;
        ///// <summary>収束判定条件</summary>
        //protected McConvergenceInfo m_csConvergeCondInfo=null;

        /// <summary>接続情報リスト</summary>      
        protected LinkedList<McConnection> m_csConnectionList = new LinkedList<McConnection>();


        /// <summary>計算状態</summary>
        protected long m_lStatus = DEFAULT_STATE;

        /// <summary>デフォルト</summary>
        internal static long DEFAULT_STATE = -1;
        /// <summary>初期化完了状態</summary>
        internal static long INITIAL_STATE = 1;
        /// <summary>計算中状態</summary>
        internal static long CALCULATION_STATE = 2;
        /// <summary>中断状態</summary>
        internal static long PAUSE_STATE = 3;
        /// <summary>再開段階状態</summary>
        internal static long RESTART_STATE = 4;
        /// <summary>強制終了状態</summary>
        internal static long STOP_STATE = 5;
        /// <summary>計算完了状態</summary>
        internal static long END_STATE = 6;


        /// <summary> Ｇｒ化要素独自のδＴ(m_csDltTime)が設定されているか = true は設定ずみ </summary>
        protected bool m_bOwnDltTSetFlg = false;
        /// <summary> DataFusion()発行のタイミング（演算フロー制御）
        /// （同期：全ての要素が演算終了後DataFutionを行う／非同期：要素が演算終了後個別にDataFutionを行う） </summary>
        protected McDefine.DataFusionTiming m_eDtFusionTiming = McDefine.DataFusionTiming.ASYNCHRONOUS;

        ///// <summary> 演算フロー制御か？（=true:フロー制御演算、=false:フロー制御ではない） </summary>
        //protected bool m_bFlowCtlFlg = false;

        /// <summary>ノード（内部処理計算用）</summary>
        protected LinkedListNode<McElement> m_csElmNode = null;
        /// <summary>要素（内部処理計算用）</summary>
        protected McElement m_csElementWork = null;


        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McGrElementCtl csObj = new McGrElementCtl( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McGrElementCtl()
        {
            m_eDtFusionTiming = McDefine.DataFusionTiming.ASYNCHRONOUS; // 非同期をデフォルト化
        }

        /// <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 virtual void SetSolutionType(McDefine.SolutionType elType)
        {
            m_elSolutionType = elType;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルの解法を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDefine.SolutionType eSolutionType = GetSolutionType()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>解法（McCalculateModelBase.NORMAL_TYPE/CONVERGENCE_TYPE）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McDefine.SolutionType GetSolutionType()
        {
            return m_elSolutionType;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>中継端子の導通設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>MakeContinuity( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void MakeContinuity()
        {
            //内部の要素の計算結果を　csOutputDataListに反映させる
            McInnerRcvPort csInnerPort = null;
            int iSndPortNum = m_csSendPortList.Count;
            for (int iPt = 0; iPt < iSndPortNum; iPt++)
            {
                csInnerPort = ((McSendTrnsPort)m_csSendPortList[iPt]).GetInnerRcvPort();
                csInnerPort.MakeContinuity();
            }

            // 内部に含まれるモデルを舐めて、グループ化要素ならば設定を行わせる
            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 is McGrElement)
                {
                    ((McGrElement)m_csElementWork).MakeContinuity();
                }
                m_csElmNode = m_csElmNode.Next;
            }
            //McReceiveTrnsPort csRcvPort = null;
            //int iRcvPortNum = m_csReceivePortList.Count;
        }

        /// <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 virtual bool IsAbleToCalculate(ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList, ref McStructErrorInfo csErrorInf)
        {
            bool bRtn = true;
            if (m_csSimTime == null)
            {
                // ErrInfo <-- 計算時刻が無い
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, 
                      Properties.HymcoImplResources.STATEMENT_SIM_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "Simulation Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            if (m_csTgtTime == null)
            {
                // ErrorInfo
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, 
                     Properties.HymcoImplResources.STATEMENT_SIM_TRG_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "Simulation Target Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            if (m_csDltTime == null)
            {
                // errorInfo
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP,
                     Properties.HymcoImplResources.STATEMENT_SIM_DELTA_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "Simulation Delta Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            // 内部要素リスト
            // LinkedList<McElement> m_csElementList;
            // にチェックを行わせて　もしも　一つでもエラーがあればダメ
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            bool bLocalRtn = true;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                if (m_csElmNode == null)
                {
                    bRtn = false;
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, 
                         Properties.HymcoImplResources.STATEMENT_WRONG_NUM );
                   // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "Wrong element number. ");
                    break;
                }
                m_csElementWork = m_csElmNode.Value;
                bLocalRtn = m_csElementWork.IsAbleToCalculate(ref csErrorInf); // シミュレーション時刻設定
                if (bLocalRtn == false)
                {
                    bRtn = false;
                    // エラーがあっても全てのチェックを走らせる
                }
                m_csElmNode = m_csElmNode.Next;

            }

            /*
            // 内部要素の解法の整合性をチェックする
            m_csElmNode = m_csElementList.First;
            for (int lLp = 0; lLp < lElmCnt; lLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                if( CheckSuitableElementSolutionType(m_csElementWork.GetSolutionType())==false )
                {
                    bRtn = false;
                    // エラーがあっても全てのチェックを走らせる
                    csErrorInf.AddCheckErrorData(m_csElementWork.GetID(), new HySObjectKind(""),
                        "Model solution type is unmatched.");
                }
                m_csElmNode = m_csElmNode.Next;
            }
            */

            // 中継端子の道通チェック
            McInnerRcvPort csInnerPort = null;
            int iSndPortNum = m_csSendPortList.Count;
            for (int iPt = 0; iPt < iSndPortNum; iPt++)
            {
                csInnerPort = ((McSendTrnsPort)m_csSendPortList[iPt]).GetInnerRcvPort();
                if (csInnerPort.TransCheck() == false)
                {
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, 
                         Properties.HymcoImplResources.STATEMENT_CONNECT_IN_PORT );
                   // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_GROUP, "No connection Internal Relay Port.");
                    bRtn = false;
                }
            }

            return bRtn;
        }
        /*
        /// <summary><para>method outline:</para>
        /// <para>解法がマッチしているかチェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CheckSuitableElementSolutionType(eType)</para>
        /// </example>
        /// <param name="eType">解法</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>自モデルが期待している解法か否かをチェックする</para>
        /// </remarks>
        virtual protected bool CheckSuitableElementSolutionType( McDefine.SolutionType eType)
        {
            if (eType == McDefine.SolutionType.NORMAL_TYPE)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        */
        /// <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</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        public virtual bool ReceiveConnectionCheck(ref HySDataLinkedList csInputDataList, ref McStructErrorInfo csErrorInf)
        {
            // Do Nothing
            return true;
        }
        /// <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</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        public virtual bool SendConnectionCheck(ref HySDataLinkedList csOutputDataList, ref McStructErrorInfo csErrorInf)
        {
            // Do Nothing
            return true;
        }

        /// <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 abstract long CheckCalculationOrder();

        /// <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 = true;
            bool bLclRtn = true;
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;

                m_csElementWork.SetSimulationTime(m_csSimTime); // シミュレーション時刻設定

                bLclRtn = m_csElementWork.SimInitialize();
                if (bLclRtn != true)
                {
                    bRtn = false;
                }
                else
                {
                    m_csElementWork.ChangeDeltaTimeAutomatically();
                }

                m_csElmNode = m_csElmNode.Next;

            }
            if (bRtn != false)
            {
                m_lStatus = McGrElementCtl.INITIAL_STATE;
                m_iNodeItemNo = 0;
                if (m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS && m_bOwnDltTSetFlg == false)
                {   // 同期（フロー制御無し）　かつ　自身のδTが未設定の場合　には、奨励δT値を設定する
                    HySTime csRcmdDlt = this.RecommendDeltaTime();
                    if (csRcmdDlt.GetTime() > 0.0d)
                    {
                        this.SetDeltaTime(csRcmdDlt);
                    }
                }
            }

            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 virtual bool InputConnectionInitialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList)
        {
            bool bRtn = true;
            bool bLclRtn = true;
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;

                bLclRtn = m_csElementWork.InputConnectionInitialize();

                m_csElmNode = m_csElmNode.Next;
            }
            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 abstract long Calculate(ref HySDataLinkedList csInputDataList);
        /*
        /// <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 FirstCalculate(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 abstract bool Calculable();

        /*
        /// <summary><para>method outline:</para>
        /// <para>モデル演算における収束判別設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetUpConvergenceInf(ref csConvergeCondInfo)</para>
        /// </example>
        /// <param name="csConvergeCondInfo">収束条件情報</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>系全体で次の計算を行う場合に呼ばれる</para>
        /// </remarks>
        public virtual long SetUpConvergenceInf(ref McConvergenceInfo csConvergeCondInfo)
        {
            // Do Nothing
            return 0;
        }
        */
        /// <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 virtual 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>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 virtual long DataFusion(ref HySDataLinkedList csOutputDataList)
        {
            long lRtn = 0;
            //内部の要素の計算結果を　csOutputDataListに反映させる
            McInnerRcvPort csInnerPort = null;
            int iSndPortNum = m_csSendPortList.Count;
            for (int iPt = 0; iPt < iSndPortNum; iPt++)
            {
                csInnerPort = ((McSendTrnsPort)m_csSendPortList[iPt]).GetInnerRcvPort();
                csInnerPort.DataTrans();
            }
            return lRtn;
        }

        /// <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 virtual bool ReadyCalculation()
        {
            bool bRtn = true;
            bool bLclRtn = true;
            if (m_csElementListForCommand == null)
            {
                return false;
            }

            int iElmCnt = m_csElementListForCommand.Count;
            m_csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                if (m_csElmNode != null)
                {
                    m_csElementWork = m_csElmNode.Value;
                    bLclRtn = m_csElementWork.ReadyCalculation();
                    if (bLclRtn == false)
                    {
                        bRtn = false;
                    }
                    m_csElmNode = m_csElmNode.Next;
                }
            }
            return bRtn;
        }
        /// <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 virtual bool CompleteCalculation()
        {
            bool bRtn = true;
            bool bLclRtn = false;
            if (m_csElementListForCommand == null)
            {
                return false;
            }

            int iElmCnt = m_csElementListForCommand.Count;
            m_csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                if (m_csElmNode != null)
                {
                    m_csElementWork = m_csElmNode.Value;
                    bLclRtn = m_csElementWork.CompleteCalculation();
                    if (bLclRtn == false)
                    {
                        bRtn = false;
                    }
                    m_csElmNode = m_csElmNode.Next;
               }

            }
            return bRtn;
        }

        /// <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 virtual bool SuspendCalculation()
        {
            bool bRtn = true;
            bool bLclRtn = false;

            if (m_csElementListForCommand == null)
            {
                return false;
            }

            int iElmCnt = m_csElementListForCommand.Count;
            m_csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                if (m_csElmNode != null)
                {
                    m_csElementWork = m_csElmNode.Value;
                    bLclRtn = m_csElementWork.SuspendCalculation();
                    if (bLclRtn == false)
                    {
                        bRtn = false;
                    }
                    m_csElmNode = m_csElmNode.Next;
                }

            }
            return bRtn;
        }

        /// <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 virtual void SetSimDataContainer(HySSimulationDataContainer csDataContainer)
        {
            if (m_csElementListForCommand != null)
            {
                int iElmCnt = m_csElementListForCommand.Count;
                m_csElmNode = m_csElementListForCommand.First;

                if (m_csElmNode != null)
                {
                    for (int iLp = 0; iLp < iElmCnt; iLp++)
                    {
                        m_csElementWork = m_csElmNode.Value;

                        m_csElementWork.SetSimDataContainer(csDataContainer);

                        m_csElmNode = m_csElmNode.Next;
                    }
                }
            }

        }

        /// <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 virtual void SetSimulationID(HySIdentifier csSimulationID)
        {
            if (m_csElementListForCommand != null)
            {
                int iElmCnt = m_csElementListForCommand.Count;
                m_csElmNode = m_csElementListForCommand.First;

                if (m_csElmNode != null)
                {
                    for (int iLp = 0; iLp < iElmCnt; iLp++)
                    {
                        m_csElementWork = m_csElmNode.Value;

                        m_csElementWork.SetSimulationID(csSimulationID);

                        m_csElmNode = m_csElmNode.Next;
                    }
                }
            }

        }

        /// <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 abstract void GainSimulationTime();
        /// <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>無し</para>
        /// </remarks>
        public virtual void ChangeDeltaTimeAutomatically()
        {
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                m_csElementWork.ChangeDeltaTimeAutomatically(); // 演算用刻み時間を自動的に変更する
                m_csElmNode = m_csElmNode.Next;

            }
        }

        //================
        // 各種設定メソッド
        //================

        /// <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;

            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 is McGrElement)
                {   // Gr化要素ならば
                    if (eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                    {   // 非同期ならば、内部も非同期である必要がある。
                        m_csElementWork.SetDataFusionTiming(eDtFusionTiming); // 非同期設定
                    }
                    else
                    {
                        m_csElementWork.SetDataFusionTiming(eDtFusionTiming); // 同期設定
                    }
                }
                else
                {   // 通常の要素
                    m_csElementWork.SetDataFusionTiming(eDtFusionTiming); // 同期／非同期設定
                }
                */
                if (m_csElementWork is McGrElement)
                {   // Gr化要素ならば
                    // Do Nothing
                }
                else
                {
                    m_csElementWork.SetDataFusionTiming(eDtFusionTiming); // 同期／非同期設定
                }
                //m_csElementWork.SetDataFusionTiming(eDtFusionTiming); // 同期／非同期設定
                m_csElmNode = m_csElmNode.Next;

            }

        }
        /// <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>SetCalInfo(csCalInfo)</para>
        /// </example>
        /// <param name="csCalInfo">演算結果格納するクラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual 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>モデル演算中の情報格納クラス(nullが返る)</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McCalInfo GetCalInfo()
        {
            return null;
        }
        /// <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>無し</para>
        /// </remarks>
        public virtual void SetSimulationTime(HySTime csCalTime)
        {
            //m_csSimTime = csCalTime;
            m_csSimTime.SetTime(csCalTime.GetTime());
            m_csSimTime.SetGeologicalYear(csCalTime.GetGeologicalYear());

            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                m_csElementWork.SetSimulationTime(m_csSimTime); // シミュレーション時刻設定
                m_csElmNode = m_csElmNode.Next;

            }
        }
        /// <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 virtual HySTime GetSimulationTime()
        {
            return m_csSimTime;
        }
        /// <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 virtual HySTime GetCalDoneTime()
        {
            return m_csSimTime;
        }
        /// <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 virtual void SetStartTime(HySTime csStartTime)
        {
            //m_csStartTime = csStartTime;
            m_csStartTime.SetTime(csStartTime.GetTime());
            m_csStartTime.SetGeologicalYear(csStartTime.GetGeologicalYear());

            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                m_csElementWork.SetStartTime(csStartTime); // 開始時刻設定
                m_csElmNode = m_csElmNode.Next;

            }
        }
        /// <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>無し</para>
        /// </remarks>
        public virtual void SetTargetTime(HySTime csTgtTime)
        {
            //m_csTgtTime = csTgtTime;
            m_csTgtTime.SetTime(csTgtTime.GetTime());
            m_csTgtTime.SetGeologicalYear(csTgtTime.GetGeologicalYear());
        }
        /// <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 virtual HySTime GetTargetTime()
        {
            return m_csTgtTime;
        }
        /// <summary><para>method outline:</para>
        /// <para>最終目標時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetFinalTargetTime(csFinalTgtTime)</para>
        /// </example>
        /// <param name="csFinalTgtTime">最終目標時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void SetFinalTargetTime(HySTime csFinalTgtTime)
        {
            m_csFinalTgtTime.SetTime(csFinalTgtTime.GetTime());
            m_csFinalTgtTime.SetGeologicalYear(csFinalTgtTime.GetGeologicalYear());
            
            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 is McGrElement)
                {
                    McGrElementCtl csGrElmCtl = m_csElementWork.GetCalModel() as McGrElementCtl;
                    if (csGrElmCtl != null)
                    {
                        csGrElmCtl.SetFinalTargetTime(csFinalTgtTime);
                    }
                }
                m_csElmNode = m_csElmNode.Next;

            }
        }

        /// <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 virtual void SetNextTargetTime(ref HySTime csCalTime, ref HySTime csDltTime)
        {
            //m_csTgtTime = csCalTime + csDltTime; // 速度アップのため　＋演算子の使用は控える
            m_csTgtTime.SetTime(csCalTime.GetTime() + csDltTime.GetTime()); 

            // 次の演算目標時刻がシミュレーション終了時刻を越えないかどうか確認
            if (m_csTgtTime.Before(m_csFinalTgtTime) != true)
            {
                // 超える場合、次の演算目標時刻をシミュレーション終了時刻に設定
                this.SetTargetTime(m_csFinalTgtTime);
                // 判定フラグの更新
                m_bExceedGoalTimeFlg = true;
            }

            if (m_bOwnDltTSetFlg != true || m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
            {   // 同期通信（フロー制御）の場合には必ず設定、あるいは、自身の時刻が設定されていない場合には、設定
                this.SetDeltaTime(csDltTime);  // Ｇｒ化要素の場合には、自分のδＴは上位の　要素のδＴに一致化させる（重要）
            }
            
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;

                if (m_bExceedGoalTimeFlg == true)
                {
                    m_csElementWork.SetTargetTime(m_csFinalTgtTime);// 下位のモデルに対して演算目標時刻をシミュレーション終了時刻に設定
                }
                else
                {
                    m_csElementWork.SetNextTargetTime(ref m_csSimTime, ref m_csDltTime); // 下位のモデルに対しては自分のδＴを用いて設定させる
                }

                m_csElmNode = m_csElmNode.Next;
            }
        }
        /// <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>本設定を行わない場合、グループ化要素を保持している要素のδＴど同じになる</para>
        /// </remarks>
        public virtual void SetDeltaTime(HySTime csDltTime)
        {
            m_bOwnDltTSetFlg = true;
            //m_csDltTime = csDltTime;
            m_csDltTime.SetTime(csDltTime.GetTime());
            m_csDltTime.SetGeologicalYear(csDltTime.GetGeologicalYear());
        }
        /// <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 virtual HySTime GetDeltaTime()
        {
            return m_csDltTime;
        }
        /// <summary><para>method outline:</para>
        /// <para>グループ化要素の独自演算刻み時間設定を解除する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ResetDeltaTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void ResetDeltaTime()
        {
            m_bOwnDltTSetFlg = false;
        }
        /// <summary><para>method outline:</para>
        /// <para>グループのδTの奨励値を計算する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySTime csDltT = RecommendDeltaTime()</para>
        /// </example>
        /// <param name=""></param>
        /// <returns>グループのδTの奨励値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>奨励値が計算できない場合には　負の値が返る</para>
        /// </remarks>
        public virtual HySTime RecommendDeltaTime()
        {
            double dDlt = 60.0d;
            if (this.m_csDltTime != null)
            {
                dDlt = this.m_csDltTime.GetTime();
                if (dDlt <= 0.0d)
                {
                    dDlt = -1.0d;
                }
            }
            HySTime csRtn = new HySTime(dDlt);
            HySTime csMin = new HySTime(366, 0, 0, 0);
            HySTime csWorkTm = new HySTime(-366, 0, 0, 0);
            bool bMinSetFlg = false;
            int iElmCnt = m_csElementListForCommand.Count;
            m_csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;

                if ((m_csElementWork.GetCalModel() is McGrElementCtl) == true)
                {
                    csWorkTm = ((McGrElementCtl)(m_csElementWork.GetCalModel())).RecommendDeltaTime() * 2.0d;
                }
                else if ((m_csElementWork.GetCalModel() is McStateCalModelBase) == true)
                {
                    // 何もしない
                }
                else
                {
                    csWorkTm = m_csElementWork.GetCalModel().GetDeltaTime();
                }
                if (csWorkTm.GetTime() > 0.0d &&
                    csWorkTm.GetTime() < csMin.GetTime())
                {
                    csMin.SetTime(csWorkTm.GetTime());
                    bMinSetFlg = true;
                }

                m_csElmNode = m_csElmNode.Next;
            }
            if (bMinSetFlg == true)
            {
                csRtn = csRtn.SetTime( csMin.GetTime() * 0.5d );
            }
            return csRtn;
        }

        /// <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)
        {
            int iElmCnt = m_csElementList.Count;
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                m_csElementWork = m_csElmNode.Value;
                m_csElementWork.SetSimuGoalTime(csTm); // シミュレーション最終目的時刻（系全体として）を設定する
                m_csElmNode = m_csElmNode.Next;
            }
        }

        //====================
        // その他必要なメソッド
        //====================


        /// <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 abstract HySKind GetModelKind();
        /// <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;
        }

        //====================
        // グループ制御固有のメソッド
        //====================
        // 計算リセットメソッド
        // 構築等　必要なメソッドは未だあるハズ
        // reset : m_iNodeItemNo=0を設定する等が必要

        /// <summary><para>method outline:</para>
        /// <para>グループ内エレメントリスト設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetElementList( csElementList, ForCommandForCommand ) </para>
        /// </example>
        /// <param name="csElementList">要素リスト</param>
        /// <param name="ForCommandForCommand">指示制御用要素リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        internal void SetElementList(LinkedList<McElement> csElementList, LinkedList<McElement> ForCommandForCommand)
        {
            m_csElementList = csElementList;
            m_csElementListForCommand = ForCommandForCommand;
        }
        /// <summary><para>method outline:</para>
        /// <para>グループ外への送信端子リスト情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSendPortList( csSndPortList ) </para>
        /// </example>
        /// <param name="csSndPortList">グループ外送信端子リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        internal void SetSendPortList(List<McSendPort> csSndPortList)
        {
            m_csSendPortList = csSndPortList;
        }
        /// <summary><para>method outline:</para>
        /// <para>グループ内接続リスト設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetConnectionList( csConnectionList ) </para>
        /// </example>
        /// <param name="csConnectionList">接続リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        internal void SetConnectionList(LinkedList<McConnection> csConnectionList)
        {
            m_csConnectionList = csConnectionList;
        }

        /*
        /// <summary><para>method outline:</para>
        /// <para>内部演算モデル作成処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ModelConstruction(csStructInfo , csModelFactorySet , ref csCheckInf) </para>
        /// </example>
        /// <param name="csStructInfo">モデル構造データ</param>
        /// <param name="csModelFactorySet">モデルファクトリ</param>
        /// <param name="csCheckInf">接続エラー情報</param>
        /// <returns>true</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool ModelConstruction(McStructGroupElement csStructInfo, McModelFactorySet csModelFactorySet, ref McStructCheckData csCheckInf)
        {
            // 何もしない
            return true;
        }
        */
        /// <summary><para>method outline:</para>
        /// <para>計算強制終了</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>StopCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void StopCalculation()
        {
            m_lStatus = McGrElementCtl.STOP_STATE;

            // 下位のＧｒ要素に通達 <-- スレッド動作により、m_csElementListを操作している最中、別スレッドから　m_csElementListを操作してはならない。
            // 従って、m_csElementListForCommand を利用して　通達を行う
            McGrElement csGrElm;
            int iElmCnt = m_csElementListForCommand.Count;
            LinkedListNode<McElement> csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csGrElm = csElmNode.Value as McGrElement;
                if (csGrElm != null)
                {   // 下位にＧｒ要素があるならば
                    csGrElm.StopCalculation();
                }
                csElmNode = csElmNode.Next;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>計算中断</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PauseCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void PauseCalculation()
        {
            m_lStatus = McGrElementCtl.PAUSE_STATE;

            // 下位のＧｒ要素に通達 <-- スレッド動作により、m_csElementListを操作している最中、別スレッドから　m_csElementListを操作してはならない。
            // 従って、m_csElementListForCommand を利用して　通達を行う
            McGrElement csGrElm;
            int iElmCnt = m_csElementListForCommand.Count;
            LinkedListNode<McElement> csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csGrElm = csElmNode.Value as McGrElement;
                if (csGrElm != null)
                {   // 下位にＧｒ要素があるならば
                    csGrElm.PauseCalculation();
                }
                csElmNode = csElmNode.Next;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>計算再開</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>RestartCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void RestartCalculation()
        {
            m_lStatus = McGrElementCtl.RESTART_STATE;

            // 下位のＧｒ要素に通達 <-- スレッド動作により、m_csElementListを操作している最中、別スレッドから　m_csElementListを操作してはならない。
            // 従って、m_csElementListForCommand を利用して　通達を行う
            McGrElement csGrElm;
            int iElmCnt = m_csElementListForCommand.Count;
            LinkedListNode<McElement> csElmNode = m_csElementListForCommand.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csGrElm = csElmNode.Value as McGrElement;
                if (csGrElm != null)
                {   // 下位にＧｒ要素があるならば
                    csGrElm.RestartCalculation();
                }
                csElmNode = csElmNode.Next;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>シミュレーション計算の進捗を取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> long lPrg = GetSimulationProgress(  ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>進捗（０～１００％）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual long GetSimulationProgress( )
        {
            long lRtn = 0;

            double dSpan = 0.0d;
            double dPass = 0.0d;

            if (m_csTgtTime.GetGeologicalYear() == 0)
            {   // 一般年代ならば
                dSpan = m_csTgtTime.GetTime() - m_csStartTime.GetTime();
                dPass = m_csSimTime.GetTime() - m_csStartTime.GetTime();
            }
            else
            {   // 地質年代ならば
                dSpan = m_csTgtTime.GetGeologicalYear() - m_csStartTime.GetGeologicalYear();
                dPass = m_csSimTime.GetGeologicalYear() - m_csStartTime.GetGeologicalYear();
            }
            if (dSpan != 0.0d)
            {
                lRtn = (long)(dPass / dSpan * 100.0d);
            }
            return lRtn;
        }

        /// <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 abstract bool SetOnlineProperty(McPropertyInfoRoot csPropertyInfo);
        /// <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 abstract bool OnlineInitialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList);


        /// <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 virtual McCmnElementOutData CreateOutData()
        {
            return null;
        }
        //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
        // 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 abstract long InitialDataFusionForConvergentCalculation();
        public virtual long InitialDataFusionForConvergentCalculation(double dErrorVal)
        {
            int iElmCnt = m_csElementList.Count;  // グループ内のエレメント数取得
            m_csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {                  // 2-2-2 演算エレメント本体
                m_csElementWork = m_csElmNode.Value;    // エレメント取得
                m_csElementWork.InitialDataFusionForConvergentCalculation(dErrorVal);
                m_csElmNode = m_csElmNode.Next;
            }
            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;
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイルにモデル内情報を全て書き出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileOUT(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>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>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> Memorize() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public virtual void Memorize()
        {
            //m_csMemoryCalInfo = m_csCalInfo.Clone();
            m_csMemorySimTime = m_csSimTime.Clone();
            m_csMemoryTotalPassingTime = m_csTotalPassingTime.Clone();

        }
        /// <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 virtual void Remember()
        {
            //m_csCalInfo = m_csMemoryCalInfo;
            m_csSimTime = m_csMemorySimTime;
            m_csTotalPassingTime = m_csMemoryTotalPassingTime;
        }


        ///// <summary>要素内演算中データ保存</summary>
        //protected McCalInfo m_csMemoryCalInfo = null;
        /// <summary>演算時刻保存</summary>
        protected HySTime m_csMemorySimTime = null;
        /// <summary>演算経過時刻保存</summary>
        protected HySTime m_csMemoryTotalPassingTime = null;
    }
}
