using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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

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

using CommonMP.HYMCO.CoreOptionl.HymcoExpansionModel;
using CommonMP.HYMCO.Ocean.McOceanBaseModel;

namespace CommonMP.HYMCO.Ocean.McOceanSampleModels
{
    /// <summary><para>class outline:</para>
    /// <para> 溶融ガス(主にO2,CO2)  モデルクラス</para>
    ///  O2 一般に魚介類が生存するためには3mg/L以上、好気性微生物が活発に活動するためには2mg/L以上が必要
    ///     溶存酸素量　dissolved oxygen :DO 
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[2021/12/31][新規作成]</para>
    public class MzOceanDissolveGass : MzOceanModelElement
    {
        /// <summary> 演算データ（キャスト用） </summary>
        MzOceanDissolveGassCalInfo m_OcLyrMdlInf = null; // 便利の為、キャスト用に定義しておく

        //========================================================
        // 光合成ＣＯ２吸収： McOceanBaseDefine.CO2_ABSORPTION
        protected McPatternRdvSndTranInfoPair m_csRcvPhytoCO2Cnnct = new McPatternRdvSndTranInfoPair();
        protected McPatternRdvSndTranInfoPair m_csSndPhytoCO2Cnnct = new McPatternRdvSndTranInfoPair();

        // ガスの溶融・放出： McOceanBaseDefine.GASS_DISSOLVE
        protected McPatternRdvSndTranInfoPair m_csRcvGassDissolveCnnct = new McPatternRdvSndTranInfoPair();
        protected McPatternRdvSndTranInfoPair m_csSndDmyCnnct = new McPatternRdvSndTranInfoPair();

        //----------------------------------
        public MzOceanDissolveGass()
        {
        }

        public MzOceanDissolveGassCalInfo GetDslvGasCalInfo(long x, long y)
        {
            return m_OcLyrMdlInf;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CheckReceiveDataConnection(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool CheckReceiveDataConnection(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            // チェック処理を入れる
            bool bRtn = base.CheckReceiveDataConnection(ref csErrorInf, lInputDataNum, csInputCellData);

            //  これは、親クラスで行われている
            //   親クラスで設定した m_csSndBreathingCnnctを使用する

            // 光合成CO2吸収
            (m_csRcvPhytoCO2Cnnct, m_csSndPhytoCO2Cnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.CO2_ABSORPTION);
            // m_csRcvPhytoCO2Cnnctは使用せず

            // 大気からのガス溶融
            (m_csRcvGassDissolveCnnct, m_csSndDmyCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.GASS_DISSOLVE);
       
            // ディバッグ用送信データ
            //m_csDebugSendCnnct = this.PrepareSndPattern(MzOceanBaseDefine.DEBUG_OUT);
            return bRtn;
        }
        ///// <summary><para>method outline:</para>
        ///// <para>出力側の接続情報チェック</para>
        ///// </summary>
        ///// <example><para>usage:</para>
        ///// <para>bool bRtn = CheckSendDataConnection(ref csErrorInf)</para>
        ///// </example>
        ///// <param name="csErrorInf">エラー出力</param>
        ///// <param name="lOutputDataNum">出力情報数</param>
        ///// <param name="csOutputCellData">出力情報配列</param>
        ///// <returns>=true:正常、=false:異常</returns>
        ///// <exception cref="">無し</exception>
        ///// <remarks><para>remarks:</para>
        ///// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        ///// </remarks>
        //protected override bool CheckSendDataConnection(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
        //{
        //    // チェック処理を入れる
        //    bool bRtn = base.CheckSendDataConnection(ref csErrorInf, lOutputDataNum, csOutputCellData);
        //    return bRtn;
        //}


        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            m_OcLyrMdlInf.Clear();
            bool bRtn = base.Initialize(ref csInitialData, lInputDataNum, ref csInputCellData);

            McInitialInfo csInDt = csInitialData as McInitialInfo;
            if (csInDt != null)
            {   // 初期化情報有り
                m_OcLyrMdlInf.m_DaySec = 0.0;

                // 演算ステップ時刻設定
                csInDt.GetInfo("O2_TotalMass_L0", ref m_OcLyrMdlInf.m_O2[0]);
                csInDt.GetInfo("O2_TotalMass_L1", ref m_OcLyrMdlInf.m_O2[1]);
                csInDt.GetInfo("O2_TotalMass_L2", ref m_OcLyrMdlInf.m_O2[2]);
                csInDt.GetInfo("O2_TotalMass_L3", ref m_OcLyrMdlInf.m_O2[3]);
                csInDt.GetInfo("O2_TotalMass_L4", ref m_OcLyrMdlInf.m_O2[4]);
                csInDt.GetInfo("O2_TotalMass_L5", ref m_OcLyrMdlInf.m_O2[5]);
                csInDt.GetInfo("O2_TotalMass_L6", ref m_OcLyrMdlInf.m_O2[5]);
                csInDt.GetInfo("CO2_TotalMass_L0", ref m_OcLyrMdlInf.m_CO2[0]);
                csInDt.GetInfo("CO2_TotalMass_L1", ref m_OcLyrMdlInf.m_CO2[1]);
                csInDt.GetInfo("CO2_TotalMass_L2", ref m_OcLyrMdlInf.m_CO2[2]);
                csInDt.GetInfo("CO2_TotalMass_L3", ref m_OcLyrMdlInf.m_CO2[3]);
                csInDt.GetInfo("CO2_TotalMass_L4", ref m_OcLyrMdlInf.m_CO2[4]);
                csInDt.GetInfo("CO2_TotalMass_L5", ref m_OcLyrMdlInf.m_CO2[5]);
                csInDt.GetInfo("CO2_TotalMass_L6", ref m_OcLyrMdlInf.m_CO2[6]);

                m_OcLyrMdlInf.m_SurfaceO2 = m_OcLyrMdlInf.m_O2[0];
                m_OcLyrMdlInf.m_SurfaceCO2 = m_OcLyrMdlInf.m_CO2[0];

                for (int ll = 0; ll < m_OcLyrMdlInf.m_lLayerNumber; ll++)
                {
                    m_OcLyrMdlInf.m_AvailableCO2[ll] = m_OcLyrMdlInf.m_CO2[ll];
                    m_OcLyrMdlInf.m_AvailableO2[ll] = m_OcLyrMdlInf.m_O2[ll];
                }

                for (int i = 0; i < m_csSndPhytoCO2Cnnct.m_RcvInfNum; i++)
                {
                    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                    {
                         m_csSndPhytoCO2Cnnct.m_dSendRatioData[i][ll]=1.0;
                    }
                }
                for (int i = 0; i < m_csSndBreathingCnnct.m_RcvInfNum; i++)
                {
                    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                    {
                        m_csSndBreathingCnnct.m_dSendRatioData[i][ll] =1.0;
                    }
                }
 
            }
 

            return bRtn;
        }

        /// <summary>
        /// 受信
        /// </summary>
        protected override void ReceiveData()
        {
            // 光合成CO2吸収
            ReceivePhytoCO2Absorption();

            // 呼吸関係
            ReceiveBREATHING();

            // 大気からの溶け込み
            ReceiveGassDissolve();
            return;
        }

        /// <summary>
        /// 送信例
        /// </summary>
        protected override void SendData()
        {
            // 光合成O2排出
            SendPhytoCO2Absorption();

            // 呼吸関係
            SendBREATHING();

            // 大気への放出
            SendGassDissolve();

            // Debug
            SendDEBUG();
            return;
        }

        //------------------
        /// <summary>
        /// 光合成O2排出：受信
        /// </summary>
        protected virtual void ReceivePhytoCO2Absorption()
        {
            //------------------------
            // 送る側（ガス側）                  
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                m_OcLyrMdlInf.m_ReqedCO2[ll] =  1.0E-8;
            }
            for (int i = 0; i < m_csSndPhytoCO2Cnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csSndPhytoCO2Cnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
                if (csCell != null)
                {
                    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                    {
                        // O2
                        m_csOcnBacedlInf.m_O2[ll] += csCell[ll].m_dData[0];
                        m_OcLyrMdlInf.m_SumO2Emission[ll] += csCell[ll].m_dData[0];

                        // ReqCO2
                        m_csSndPhytoCO2Cnnct.m_dRcvRatioData[i][ll] = csCell[ll].m_dData[1];   // 分配の為、要求量を覚えておく
                        m_OcLyrMdlInf.m_ReqedCO2[ll] += csCell[ll].m_dData[1];
                    }
                }
            }
            // 配分
            for (int i = 0; i < m_csSndPhytoCO2Cnnct.m_RcvInfNum; i++)
            {
                for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                {
                    m_csSndPhytoCO2Cnnct.m_dSendRatioData[i][ll] = m_csSndPhytoCO2Cnnct.m_dRcvRatioData[i][ll] / m_OcLyrMdlInf.m_ReqedCO2[ll];   // 分配の為、要求量を覚えておく
                }

            }
            //// 光合成側：
            //for (int i = 0; i < m_csRcvPhytoCO2Cnnct.m_RcvInfNum; i++)
            //{
            //    HySCellData[] csCell = m_csRcvPhytoCO2Cnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
            //    if (csCell != null)
            //    {
            //        for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            //        {
            //            // O2
            //            m_csOcnBacedlInf.m_O2[ll] += csCell[ll].m_dData[0];
            //        }
            //    }
            //}
            }

        /// <summary>
        /// 光合成CO2吸収：送信
        /// 　　CO2は豊富にあり、要求量そのままが供給できるとする
        /// </summary>
        protected virtual void SendPhytoCO2Absorption()
        {
            HySCellData[] csSndDt = null;
            ////光合成側：
            //// O2量、排気ガス
            //for (int i = 0; i < m_csRcvPhytoCO2Cnnct.m_RcvInfNum; i++)
            //{
            //    csSndDt = m_csRcvPhytoCO2Cnnct.m_csSndInfArry[i].PrepareSendCellD1();
            //    if (csSndDt == null) { break; }
            //    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            //    {
            //        csSndDt[ll].m_dData[0] = m_csOcnBacedlInf.m_O2Prduct[ll];
            //        csSndDt[ll].m_dData[1] = m_csOcnBacedlInf.m_ReqO2[ll];
            //    }
            //}
            //送る側（ガス側）
            // CO2量
            for (int i = 0; i < m_csSndPhytoCO2Cnnct.m_RcvInfNum; i++)
            {
                csSndDt = m_csSndPhytoCO2Cnnct.m_csSndInfArry[i].PrepareSendCellD1();
                if (csSndDt == null) { break; }
                for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                {
                    csSndDt[ll].m_dData[0] = m_OcLyrMdlInf.m_AvailableCO2[ll] * m_csSndPhytoCO2Cnnct.m_dSendRatioData[i][ll];
                    m_OcLyrMdlInf.m_SumCO2Emission[ll] -= csSndDt[ll].m_dData[0];
                }
            }
            //McLog.DebugOut("MzOceanDissolveGass", "SendPhytoCO2Absorption", "END");
        }

        //------------------
        /// <summary>
        /// 大気からの溶け込み：受信
        /// </summary>
        protected virtual void ReceiveGassDissolve()
        {
            // 最上面に溶け込む
            for (int i = 0; i < m_csRcvGassDissolveCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csRcvGassDissolveCnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
                if (csCell != null)
                {
                    m_OcLyrMdlInf.m_O2[0] += csCell[0].m_dData[0];
                    m_OcLyrMdlInf.m_CO2[0] += csCell[0].m_dData[1];
                    m_OcLyrMdlInf.m_Gass1[0] += csCell[0].m_dData[2];
                }
            }
        }

        /// <summary>
        /// 大気への放出
        /// </summary>
        protected virtual void SendGassDissolve()
        {
            HySCellData[] csSndDt = null;

            for (int i = 0; i < m_csRcvGassDissolveCnnct.m_RcvInfNum; i++)
            {
                csSndDt = m_csRcvGassDissolveCnnct.m_csSndInfArry[i].PrepareSendCellD1();
                if (csSndDt == null) { break; }
                csSndDt[0].m_dData[0] = m_OcLyrMdlInf.m_Emission_O2;
                csSndDt[0].m_dData[1] = m_OcLyrMdlInf.m_Emission_CO2;
                csSndDt[0].m_dData[2] = m_OcLyrMdlInf.m_SurfaceO2;
                csSndDt[0].m_dData[3] = m_OcLyrMdlInf.m_SurfaceCO2;
                //csSndDt[0].m_dData[2] = m_csOcnBacedlInf.m_ReqO2[0];
            }
            //McLog.DebugOut("MzOceanDissolveGass", "SendGassDissolve", "END");
        }

        //-------- 
        /// <summary>
        /// 呼吸：受信
        /// </summary>
        protected override void ReceiveBREATHING()
        {
            //------------------------
            // 要求される側（ガス側）
            //   CO2受信、O2要求受診
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                m_OcLyrMdlInf.m_ReqedO2[ll] = 1.0E-8;
            }
            for (int i = 0; i < m_csSndBreathingCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csSndBreathingCnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
                if (csCell != null)
                {
                    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                    {
                        m_OcLyrMdlInf.m_ReqedO2[ll] += csCell[ll].m_dData[0];
                        m_csSndBreathingCnnct.m_dRcvRatioData[i][ll] = csCell[ll].m_dData[0];   // 分配の為、要求量を覚えておく

                        m_csOcnBacedlInf.m_CO2[ll] += csCell[ll].m_dData[1];
                        m_OcLyrMdlInf.m_SumCO2Emission[ll] += csCell[ll].m_dData[1];

                        m_csOcnBacedlInf.m_Gass1[ll] += csCell[ll].m_dData[2];
                        m_csOcnBacedlInf.m_Gass2[ll] += csCell[ll].m_dData[3];
                    }
                }
            }
            // 配分量
            for (int i = 0; i < m_csSndBreathingCnnct.m_RcvInfNum; i++)
            {
                for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                {
                    m_csSndBreathingCnnct.m_dSendRatioData[i][ll] = m_csSndBreathingCnnct.m_dRcvRatioData[i][ll] / m_OcLyrMdlInf.m_ReqedO2[ll];   // 分配の為、要求量を覚えておく
                }
            }
            //----------------------------
            //// 呼吸者：
            //for (int i = 0; i < m_csRcvBreathingCnnct.m_RcvInfNum; i++)
            //{
            //    HySCellData[] csCell = m_csRcvBreathingCnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
            //    if (csCell != null)
            //    {
            //        for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            //        {
            //            m_csOcnBacedlInf.m_O2[ll] += csCell[ll].m_dData[0];
            //        }
            //    }
            //}
        }

        /// <summary>
        /// 呼吸：送信
        /// </summary>
        protected override void SendBREATHING( )
        {
            HySCellData[] csSndDt = null;
            ////呼吸者
            //// 供給O2量、排気ガス
            //for (int i = 0; i < m_csRcvBreathingCnnct.m_RcvInfNum; i++)
            //{
            //    csSndDt = m_csRcvBreathingCnnct.m_csSndInfArry[i].PrepareSendCellD1();
            //    if (csSndDt == null) { break; }
            //    for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            //    {
            //        //csSndDt[ll].m_dData[0] = m_csOcnBacedlInf.m_ReqO2[ll];
            //        //csSndDt[ll].m_dData[1] = m_csOcnBacedlInf.m_CO2[ll];
            //        //csSndDt[ll].m_dData[2] = m_csOcnBacedlInf.m_Gass1[ll];
            //        //csSndDt[ll].m_dData[3] = m_csOcnBacedlInf.m_Gass2[ll];
            //    }
            //}
            //----------------
            //ガス側
            // O2量：：供給可能なO2を分配して供給
            for (int i = 0; i < m_csSndBreathingCnnct.m_RcvInfNum; i++)
            {
                csSndDt = m_csSndBreathingCnnct.m_csSndInfArry[i].PrepareSendCellD1();
                if (csSndDt == null) { break; }
                for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
                {
                    csSndDt[ll].m_dData[0] = m_OcLyrMdlInf.m_AvailableO2[ll] * m_csSndBreathingCnnct.m_dSendRatioData[i][ll];
                    m_OcLyrMdlInf.m_SumO2Emission[ll] -= csSndDt[ll].m_dData[0];
                }
            }
            //McLog.DebugOut("MzOceanDissolveGass", "SendDEBUG", "END");
        }

        /// <summary>
        /// ディバッグ出力
        /// </summary>
        protected virtual void SendDEBUG()
        {
            for (int i = 0; i < m_csDebugSendCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csDebugSendCnnct.m_csSndInfArry[i].PrepareSendCellD1();
                for (int ll = 0; ll < m_OcLyrMdlInf.m_lLayerNumber; ll++)
                {
                    csCell[ll].m_dData[0] = m_OcLyrMdlInf.m_O2[ll];
                    csCell[ll].m_dData[1] = m_OcLyrMdlInf.m_CO2[ll];
                    csCell[ll].m_dData[2] = m_OcLyrMdlInf.m_meanO2Emission[ll];
                    csCell[ll].m_dData[3] = m_OcLyrMdlInf.m_meanCO2Emission[ll];
                }
            }
            //McLog.DebugOut("MzOceanDissolveGass", "SendDEBUG", "END");
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate(ref csInputDataList)</para>
        /// </example>
        /// <param name="lOnlyReceveDataNum">入力だけの情報数</param>
        /// <param name="csOnlyReceiveCellData">入力だけの情報配列</param>
        /// <param name="lOnlySendDataNum">出力だけの情報数</param>
        /// <param name="csOnlySelDataCellData">出力だけの情報配列</param>
        /// <param name="lRcvSndDataNum">相互接続報数</param>
        /// <param name="csReceiveCellData">相互接続入力側情報配列</param>
        /// <param name="csSelDataCellData">相互接続出力側情報配列</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>派生クラス側で必ずオーバライドする必要がある</para>
        /// </remarks>
        protected override long Calculate(
            long lOnlyReceveDataNum, ref McReceiveOnlyTranInfo[] csOnlyReceiveCellData,
            long lOnlySendDataNum, ref McSendOnlyTranInfo[] csOnlySelDataCellData,
            long lRcvSndDataNum, ref McRdvSndTranInfoPair[] csRcvSndCelDataCellData
            )
        {
            double dT = m_csDltTime.GetTime() / (3600.0 * 24.0);

            // --------------------------------
            // 生物からの影響
            // 提供可能なCO２量計算  m_AvailableCO2
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                if (m_OcLyrMdlInf.m_CO2[ll] > m_OcLyrMdlInf.m_ReqedCO2[ll])
                {
                    m_OcLyrMdlInf.m_AvailableCO2[ll] = m_OcLyrMdlInf.m_ReqedCO2[ll];
                }
                else
                {
                    m_OcLyrMdlInf.m_AvailableCO2[ll] = m_OcLyrMdlInf.m_CO2[ll];
                }
                m_OcLyrMdlInf.m_CO2[ll] -= m_OcLyrMdlInf.m_AvailableCO2[ll];
            }
            // 生物からの影響
            // 提供可能なＯ２量計算  m_AvailableO2
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                if(m_OcLyrMdlInf.m_O2[ll] > m_OcLyrMdlInf.m_ReqedO2[ll])
                {
                    m_OcLyrMdlInf.m_AvailableO2[ll] = m_OcLyrMdlInf.m_ReqedO2[ll];
                }
                else
                {
                    m_OcLyrMdlInf.m_AvailableO2[ll] = m_OcLyrMdlInf.m_O2[ll];
                }
                m_OcLyrMdlInf.m_O2[ll] -= m_OcLyrMdlInf.m_AvailableO2[ll];
            }

            //-------------------------------
            // 大気圏への排出 計算前
            m_OcLyrMdlInf.m_SurfaceO2 = m_OcLyrMdlInf.m_O2[0]; 
            m_OcLyrMdlInf.m_SurfaceCO2 = m_OcLyrMdlInf.m_CO2[0];

            // 大気の溶け込み　＜＜＜　ReceiveGassDissolve（）内で行う
            // 大気へ放出する気体の計算
            m_OcLyrMdlInf.m_Emission_O2 = dT * (m_OcLyrMdlInf.m_SurfaceO2 - MzOceanDissolveGassCalInfo.S_O2);// * m_OcLyrMdlInf.m_dLayerLength[0];
            if (m_OcLyrMdlInf.m_Emission_O2 < 0.0) { m_OcLyrMdlInf.m_Emission_O2 = 0.0; }
            m_OcLyrMdlInf.m_Emission_CO2 = dT * (m_OcLyrMdlInf.m_SurfaceCO2 - MzOceanDissolveGassCalInfo.S_CO2);// * m_OcLyrMdlInf.m_dLayerLength[0];
            if (m_OcLyrMdlInf.m_Emission_CO2 < 0.0) { m_OcLyrMdlInf.m_Emission_CO2 = 0.0; }
      
            m_OcLyrMdlInf.m_O2[0] -= m_OcLyrMdlInf.m_Emission_O2;
            m_OcLyrMdlInf.m_CO2[0] -= m_OcLyrMdlInf.m_Emission_CO2;
            // 大気圏への排出 計算後

            //-------------------------------
            // 溶融気体の拡散
            for (int ll = 1; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                double dltG = dT * (m_OcLyrMdlInf.m_O2[ll - 1] - m_OcLyrMdlInf.m_O2[ll]) * (1E-3 / (1.0 + m_OcLyrMdlInf.m_dLayerLength[ll - 1]));
                m_OcLyrMdlInf.m_O2[ll - 1] -= dltG;
                m_OcLyrMdlInf.m_O2[ll] += dltG;
                dltG = dT * (m_OcLyrMdlInf.m_CO2[ll - 1] - m_OcLyrMdlInf.m_CO2[ll]) * (1E-3 / (1.0 + m_OcLyrMdlInf.m_dLayerLength[ll - 1]));
                m_OcLyrMdlInf.m_CO2[ll - 1] -= dltG;
                m_OcLyrMdlInf.m_CO2[ll] += dltG;
            }
            //------------------------------
            // 海洋ベルトコンベア等で運ばれてくるO2の量、運び出されるCO2の量
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                m_OcLyrMdlInf.m_O2[ll] += m_OcLyrMdlInf.m_StreamInO2[ll] * dT;
                m_OcLyrMdlInf.m_CO2[ll] -= m_OcLyrMdlInf.m_StreamOutCO2[ll] * dT;
            }

            m_OcLyrMdlInf.m_SurfaceO2 = m_OcLyrMdlInf.m_O2[0];
            m_OcLyrMdlInf.m_SurfaceCO2 = m_OcLyrMdlInf.m_CO2[0];

            //---------------------------------------------------
            //---------------------------------------------------
            // 酸素と二酸化炭素の一日の排出・吸収平均値を計算する
            m_OcLyrMdlInf.m_DaySec += m_csDltTime.TotalSec();
            if (m_OcLyrMdlInf.m_DaySec >= 24 * 3600)
            {
                for (int ll = 0; ll < m_OcLyrMdlInf.m_lLayerNumber; ll++)
                {
                    m_OcLyrMdlInf.m_meanO2Emission[ll] = m_OcLyrMdlInf.m_SumO2Emission[ll] * (24 * 3600) / m_OcLyrMdlInf.m_DaySec;
                    m_OcLyrMdlInf.m_meanCO2Emission[ll] = m_OcLyrMdlInf.m_SumCO2Emission[ll] * (24 * 3600) / m_OcLyrMdlInf.m_DaySec;

                    m_OcLyrMdlInf.m_SumO2Emission[ll] = m_OcLyrMdlInf.m_SumO2Emission[ll] * ( m_OcLyrMdlInf.m_DaySec - 24 * 3600 )/ (24*3600);
                    m_OcLyrMdlInf.m_SumCO2Emission[ll] = m_OcLyrMdlInf.m_SumCO2Emission[ll] * (m_OcLyrMdlInf.m_DaySec - 24 * 3600) / (24 * 3600);
                }
                m_OcLyrMdlInf.m_DaySec -= 24 * 3600;
            }
            //--------------------------------------------------

//// テスト用★★★仮処理：　提供可能なＯ２量計算：設定
//for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
//{ m_OcLyrMdlInf.m_AvailableO2[ll] = m_OcLyrMdlInf.m_ReqedO2[ll] + m_OcLyrMdlInf.m_O2[0]; }
//----- Debug Check ------
//McLog.DebugOut("MzOceanDissolveGass", "Calculate", "END");
//------------------------

            return 0;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetProperty(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            base.SetProperty(csCellMdlPropertyInfo);
            // 使用しやすいようにキャストしておく
            m_OcLyrMdlInf = (MzOceanDissolveGassCalInfo)m_csCalInfo;

            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
                // 各種係数設定
                csPrptyInfo.GetInfo("O2_L0", ref m_OcLyrMdlInf.m_StreamInO2[0]);
                csPrptyInfo.GetInfo("O2_L1", ref m_OcLyrMdlInf.m_StreamInO2[1]);
                csPrptyInfo.GetInfo("O2_L2", ref m_OcLyrMdlInf.m_StreamInO2[2]);
                csPrptyInfo.GetInfo("O2_L3", ref m_OcLyrMdlInf.m_StreamInO2[3]);
                csPrptyInfo.GetInfo("O2_L4", ref m_OcLyrMdlInf.m_StreamInO2[4]);
                csPrptyInfo.GetInfo("O2_L5", ref m_OcLyrMdlInf.m_StreamInO2[5]);

                csPrptyInfo.GetInfo("CO2_L0", ref m_OcLyrMdlInf.m_StreamOutCO2[0]);
                csPrptyInfo.GetInfo("CO2_L1", ref m_OcLyrMdlInf.m_StreamOutCO2[1]);
                csPrptyInfo.GetInfo("CO2_L2", ref m_OcLyrMdlInf.m_StreamOutCO2[2]);
                csPrptyInfo.GetInfo("CO2_L3", ref m_OcLyrMdlInf.m_StreamOutCO2[3]);
                csPrptyInfo.GetInfo("CO2_L4", ref m_OcLyrMdlInf.m_StreamOutCO2[4]);
                csPrptyInfo.GetInfo("CO2_L5", ref m_OcLyrMdlInf.m_StreamOutCO2[5]);
            }

            return true;
        }

    }
}
