// <summary>ソースコード：ＨＹＭＣＯ演算モデルクラス</summary>
// <author>CommonMP</author>

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

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

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


namespace CommonMP.HYMCO.Interface.Model
{
    /// <summary><para>class outline:</para>
    /// <para>演算モデルの基底クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public abstract class McCalculateModelBase : McCalModelEssential
    {
        /// <summary>要素内演算中データ</summary>
        protected McCalInfo m_csCalInfo = null;
        /// <summary>解法</summary>
        protected McDefine.SolutionType m_elSolutionType = McDefine.SolutionType.NORMAL_TYPE;

        // === 時刻関連 ===
        /// <summary>シミュレーション開始時刻</summary>
        protected HySTime m_csStartTime = HySTime.DEFAULT_TIME.Clone();
        /// <summary>シミュレーションのトータル経過時間</summary>
        protected HySTime m_csTotalPassingTime= new HySTime(0);

        /// <summary>要素内演算中データ保存</summary>
        protected McCalInfo m_csMemoryCalInfo = null;


        //=========================
        // 演算実行前処理関連メソッド
        //=========================
      
        /// <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 = true;

            if (m_csCalInfo == null)
            {
                // ErroINfo <-- 計算情報が無い
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, 
                    Properties.HymcoIFResources.STATEMENT_MCCALINFO_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "McCalInfo is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            if (m_csSimTime == null)
            {
                // ErrInfo <-- 計算時刻が無い
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, 
                    Properties.HymcoIFResources.STATEMENT_SIM_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "Simulation Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            if (m_csTgtTime == null)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, 
                     Properties.HymcoIFResources.STATEMENT_SIM_TRG_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "Simulation Target Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            if (m_csDltTime == null)
            {
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, 
                     Properties.HymcoIFResources.STATEMENT_SIM_DELTA_TIME_NO_SET );
               // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "Simulation Delta Time is not set");
                bRtn = false;
                // エラーがあっても全てのチェックを走らせる
            }
            try
            {
                if (this.ReceiveConnectionCheck(ref csInputDataList, ref csErrorInf) == false)
                {   // 入力情報チェック
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, 
                         Properties.HymcoIFResources.STATEMENT_REC_CHK_ANS_NG );
                   // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "ReceiveConnectionCheck() anser is false");
                    bRtn = false;
                }
            }
            catch (Exception ex)
            {
                // ログ出力
               // ver1.5 エラートレース日本語対応
                string  DispStatement = Properties.HymcoIFResources.STATEMENT_REC_CONNECT_CHECK + Properties.HymcoIFResources.STATEMENT_CATCH_EXCEPTION
                    + Properties.HymcoIFResources.STATEMENT_IN_CLASS + "(" + this.ToString() + ") :: " + ex.Message ;
                HySLog.LogOut(HySLog.ONLINE, "McCalculateModelBase::IsAbleToCalculate", DispStatement );
               // HySLog.LogOut(HySLog.ONLINE, "McCalculateModelBase::IsAbleToCalculate", " ReceiveConnectionCheck Exception Catch" + " in Class(" + this.ToString() + ") :: " + ex.Message); //ex.StackTrace);
                //McLog.DebugOut(GetSimulationTime(), GetID(), McLog.SYSTEM, " IsAbleToCalculate Exception Catch", " in (" + m_csCalModel.ToString() + ") :: " + ex.Message);
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(this.GetID(), McModelLibraryDefine.ELEMENT, DispStatement );
               // csErrorInf.AddSimuErrorData(this.GetID(), McModelLibraryDefine.ELEMENT, " ReceiveConnectionCheck Exception Catch" + " in Class(" + this.ToString() + ") :: " + ex.Message);
                // 異常通知
                bRtn = false;
            }
            try
            {
                if (this.SendConnectionCheck(ref csOutputDataList, ref csErrorInf) == false)
                {   // 出力情報チェック
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC,
                        Properties.HymcoIFResources.STATEMENT_SND_CHK_ANS_NG );
                   // csErrorInf.AddSimuErrorData(m_csElement.GetID(), McModelLibraryDefine.ELEMENT_CALC, "SendConnectionCheck() anser is false");
                    bRtn = false;
                }
            }
            catch (Exception ex)
            {
                // ログ出力
               // ver1.5 エラートレース日本語対応
                string DispStatement = Properties.HymcoIFResources.STATEMENT_SND_CONNECT_CHECK + Properties.HymcoIFResources.STATEMENT_CATCH_EXCEPTION
                    + Properties.HymcoIFResources.STATEMENT_IN_CLASS + "(" + this.ToString() + ") :: " + ex.Message;
                HySLog.LogOut(HySLog.ONLINE, "McCalculateModelBase::IsAbleToCalculate", DispStatement);
               // HySLog.LogOut(HySLog.ONLINE, "McCalculateModelBase::IsAbleToCalculate", " SendConnectionCheck Exception Catch" + " in Class(" + this.ToString() + ") :: " + ex.Message); //ex.StackTrace);
                //McLog.DebugOut(m_csCalModel.GetSimulationTime(), GetID(), McLog.SYSTEM, " IsAbleToCalculate Exception Catch", " in (" + m_csCalModel.ToString() + ") :: " + ex.Message);
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddSimuErrorData(this.GetID(), McModelLibraryDefine.ELEMENT, DispStatement );
               // csErrorInf.AddSimuErrorData(this.GetID(), McModelLibraryDefine.ELEMENT, " SendConnectionCheck Exception Catch" + " in Class(" + this.ToString() + ") :: " + ex.Message);
                // 異常通知
                bRtn = false;
            }

            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)
        {
            return this.Calculate();
        }
        
        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Calculate()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected abstract long Calculate();

        /// <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;
            if (m_csSimTime.Before(m_csTgtTime) != true)
            {   // 計算時刻が、目標時刻を超えたならば
                bRtn = true;
            }
            if (bRtn == false)
            {   // 先の条件で収束していないとき
                if (m_eDtFusionTiming == CommonMP.HYMCO.Interface.McDefine.DataFusionTiming.ASYNCHRONOUS)
                {   // 非同期ならば
                    // 上流の全ての要素が必要時刻まで計算されていなければ計算を開始しない
                    // 即ち　IsConverged=true で返す。（計算が行われない為、シミュレーション時刻も進行しない）
                    for (long lP = 0; lP < m_lInputDataNum; lP++)
                    {   // 入力データ数分
                        if (m_csSimTime.After(m_csInputData[lP].GetLastTime()) == true)
                        {
                            bRtn = true;
                        }
                    }
                }
            }
            return bRtn;
        }
        /*
        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>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 override long DataFusion(ref HySDataLinkedList csOutputDataList)
        {
            return DataFusion();
        }
        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected abstract long DataFusion();

        /// <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()
        {
            return true;
        }
        /// <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()
        {
            return true;
        }

        /// <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 override bool SuspendCalculation()
        {
            return true;
        }

        /// <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 override void SetSimDataContainer(HySSimulationDataContainer csDataContainer)
        {
            // 何もしない
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル内部の時刻を進める</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GainSimulationTime()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void GainSimulationTime()
        {
            m_csSimTime.Add(m_csDltTime); // m_csSimTime += m_csDltTime; <-- 速度アップの為、＋=演算子よりも　Add（）を使用したほうが良い
            m_csTotalPassingTime.SetTime(m_csSimTime.GetTime() - m_csStartTime.GetTime());
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCalInfo(csCalInfo)</para>
        /// </example>
        /// <param name="csCalInfo">演算結果格納するクラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void SetCalInfo(McCalInfo csCalInfo)
        {
            m_csCalInfo = csCalInfo;
            if (m_csCalInfo != null)
            {
                if (m_csElement != null)
                {
                    csCalInfo.SetID(m_csElement.GetID());
                }
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCalInfo csCalInfo = GetCalInfo()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>モデル演算中の情報格納クラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCalInfo GetCalInfo()
        { return m_csCalInfo; }
        /// <summary><para>method outline:</para>
        /// <para>演算時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSimulationTime(csCalTime)</para>
        /// </example>
        /// <param name="csCalTime">演算時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void SetSimulationTime(HySTime csCalTime)
        {
            //m_csSimTime = csCalTime;
            m_csSimTime.SetTime(csCalTime.GetTime());
            m_csSimTime.SetGeologicalYear(csCalTime.GetGeologicalYear());
            m_csTotalPassingTime.SetTime(m_csSimTime.GetTime() - m_csStartTime.GetTime());
            m_csTotalPassingTime.SetGeologicalYear(m_csSimTime.GetGeologicalYear() - m_csStartTime.GetGeologicalYear());
        }

        /// <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 override 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 override 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 override void SetStartTime(HySTime csStartTime)
        {
            //m_csStartTime = csStartTime;
            m_csStartTime.SetTime(csStartTime.GetTime());
            m_csStartTime.SetGeologicalYear(csStartTime.GetGeologicalYear());
        }
        /// <summary><para>method outline:</para>
        /// <para>演算目標時刻を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetTargetTime(csTgtTime)</para>
        /// </example>
        /// <param name="csTgtTime">目標時刻</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override 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 override HySTime GetTargetTime()
        {
            return m_csTgtTime;
        }
        /// <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 override void SetNextTargetTime(ref HySTime csCalTime, ref HySTime csDltTime)
        {
            //m_csTgtTime = csCalTime + csDltTime; // 速度アップの為には、＋演算子を私用しないほうが良い
            m_csTgtTime.SetTime(csCalTime.GetTime() + csDltTime.GetTime());
        }
        /// <summary><para>method outline:</para>
        /// <para>演算刻み時間を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetDeltaTime(csDltTime)</para>
        /// </example>
        /// <param name="csDltTime">演算刻み時間</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void SetDeltaTime(HySTime csDltTime)
        {
            //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 override HySTime GetDeltaTime()
        {
            return m_csDltTime;
        }
        /// <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 override void SetSolutionType(McDefine.SolutionType elType)
        {
            m_elSolutionType = elType;
        }
        /// <summary><para>method outline:</para>
        /// <para>モデルの解法を取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDefine.SolutionType eType = GetSolutionType()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>解法（McCalculateModelBase.NORMAL_TYPE/CONVERGENCE_TYPE）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McDefine.SolutionType GetSolutionType()
        { return McDefine.SolutionType.NORMAL_TYPE; }
        /// <summary><para>method outline:</para>
        /// <para>演算用刻み時間を自動的に変更する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ChangeDeltaTimeAutomatically()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>必要に応じて派生クラスでオーバーライドする。 (この場合 overrideを忘れないこと)</para>
        /// </remarks>
        public override void ChangeDeltaTimeAutomatically()
        {
            // 何らかの判断により m_csDltTime の値を変更する場合、
            // 此処にその処理を入れる
        }

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

        /// <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 override McCmnElementOutData CreateOutData()
        {
            return new McCmnElementOutData();
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイルにモデル内情報を全て書き出す</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = FileOUT(csData)</para>
        /// </example>
        /// <param name="csData">演算要素データ</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileOUT(HySDataRoot csData)
        {
            bool bRtn = true;
            if (csData == null || csData as McCmnElementOutData == null)
            {
                return false;
            }

            McCmnElementOutData csElementOutData = (McCmnElementOutData)(csData);
            // 演算モデルの保存
            csElementOutData.SetData(m_csCalInfo);
            // 時刻データの保存
            csElementOutData.SetTimeData(McDefine.SIMULATION_TIME, m_csSimTime);
            csElementOutData.SetTimeData(McDefine.START_TIME, m_csStartTime);
            csElementOutData.SetTimeData(McDefine.PASSING_TIME, m_csTotalPassingTime);
            csElementOutData.SetTimeData(McDefine.TARGET_TIME, m_csTgtTime);
            csElementOutData.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>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool FileIN(HySDataRoot csData)
        {
            //bool bCalInfoExistFlg = (bool)csFile.LoadAndDeserialize();
            //if (bCalInfoExistFlg == true)
            //{
            //    m_csCalInfo = csFile.DataRead() as McCalInfo;
            //}
            //m_csSimTime = csFile.LoadAndDeserialize() as HySTime;
            //m_csSimTime.PostDeserialize();
            //m_csTgtTime = csFile.LoadAndDeserialize() as HySTime;
            //m_csTgtTime.PostDeserialize();
            //m_csDltTime = csFile.LoadAndDeserialize() as HySTime;
            //m_csDltTime.PostDeserialize();

            bool bRtn = true;
            if (csData == null || csData as McCmnElementOutData == null)
            {
                return false;
            }

            McCmnElementOutData csElementOutData = (McCmnElementOutData)(csData);
            // 演算モデルの復元
            McCalInfo csCalInfo = csElementOutData.GetData();
            if (m_csCalInfo != null)
            {
                m_csCalInfo.CopyInfo(csCalInfo);
            }
            // 時刻データの復元
            m_csSimTime = (HySTime)csElementOutData.GetTimeData(McDefine.SIMULATION_TIME);
            m_csStartTime = (HySTime)csElementOutData.GetTimeData(McDefine.START_TIME);
            m_csTotalPassingTime = (HySTime)csElementOutData.GetTimeData(McDefine.PASSING_TIME);
            m_csTgtTime = (HySTime)csElementOutData.GetTimeData(McDefine.TARGET_TIME);
            m_csDltTime = (HySTime)csElementOutData.GetTimeData(McDefine.DELTA_TIME);
            // 復元後の整合性確保
            if (m_csCalInfo != null)
            {
                if (m_csCalInfo is HySVersionManagement)
                {
                    ((HySVersionManagement)m_csCalInfo).PostDeserialize();
                }
            }
            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;
        }

        /// <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 override void Memorize()
        {
            m_csMemoryCalInfo = m_csCalInfo.Clone();  // Clone で別インスタンス化しなければならない
            if (m_csCalInfo.GetID() != null)
            {
                m_csMemoryCalInfo.SetID(new HySID(m_csCalInfo.GetID().ToString()));
            }
            m_csMemorySimTime.SetTime( m_csSimTime);
            m_csMemoryTotalPassingTime.SetTime( m_csTotalPassingTime);
        }
        /// <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 override void Remember()
        {
            if (m_csCalInfo == null)
            {
                m_csCalInfo = m_csMemoryCalInfo.Clone();  // Clone で別インスタンス化しなければならない
                if (m_csMemoryCalInfo.GetID() != null)
                {
                    m_csCalInfo.SetID(new HySID(m_csMemoryCalInfo.GetID().ToString()));
                }
            }
            else
            {
                m_csCalInfo.CopyInfo(m_csMemoryCalInfo);
                if (m_csMemoryCalInfo.GetID() != null)
                {
                    m_csCalInfo.SetID(new HySID(m_csMemoryCalInfo.GetID().ToString()));
                }
            }
            m_csSimTime.SetTime(m_csMemorySimTime);
            m_csTotalPassingTime.SetTime( m_csMemoryTotalPassingTime);
        }

    }
}
