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> 植物プランクトン（Phytoplankton) モデルクラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[2021/12/31][新規作成]</para>
    /// </remarks>
    public class MzOceanPhytoplanktons : MzOceanModelElement
    {
        /// <summary> 演算データ（キャスト用） </summary>
        MzOceanPhytoplanktonsCalInfo m_PhytoPlanktonInf = null; // 便利の為、キャスト用に定義しておく

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


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

        /// <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_PhytoPlanktonInf = (MzOceanPhytoplanktonsCalInfo)m_csCalInfo;

            // 光合成CO2吸収
            (m_csRcvPhytoCO2Cnnct, m_csSndPhytoCO2Cnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.CO2_ABSORPTION);

            // 光合成による養分使用
            (m_csRcvFertilizerCnnct, m_csSndFertilizerCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.PHOTOSYNTHESIS);

            //McPatternRdvSndTranInfoPair csDmy;
            //// 排泄・死＿関連接続　　＜－－親クラス側で行っている
            //(csDmy, m_csSndExcretionDeath) = this.PrepareRcvSndPattern(McOceanBaseDefine.EXCRETION_DEATH);

            //// ディバッグ用送信データ
            //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_PhytoPlanktonInf.Clear();
            bool bRtn = base.Initialize(ref csInitialData, lInputDataNum, ref csInputCellData);
            McInitialInfo csInDt = csInitialData as McInitialInfo;
            if (csInDt != null)
            {   // 初期化情報有り

                // 初期量
                this.InitMass(ref csInDt);

                // 要求量初期値計算
                for (int ll = 0; ll < m_PhytoPlanktonInf.m_lLayerNumber; ll++)
                {
                    // 要求量を計算
                    m_PhytoPlanktonInf.m_ReqN[ll] = m_PhytoPlanktonInf.m_dKfN * m_PhytoPlanktonInf.m_dN0 * m_PhytoPlanktonInf.m_TotalSelfMass[ll] * m_PhytoPlanktonInf.m_dVMax;
                    m_PhytoPlanktonInf.m_ReqP[ll] = m_PhytoPlanktonInf.m_dKfP * m_PhytoPlanktonInf.m_dP0 * m_PhytoPlanktonInf.m_TotalSelfMass[ll] * m_PhytoPlanktonInf.m_dVMax;
                    m_PhytoPlanktonInf.m_ReqSi[ll] = m_PhytoPlanktonInf.m_dKfSi * m_PhytoPlanktonInf.m_dFe0 * m_PhytoPlanktonInf.m_TotalSelfMass[ll] * m_PhytoPlanktonInf.m_dVMax;
                    m_PhytoPlanktonInf.m_ReqFe[ll] = m_PhytoPlanktonInf.m_dKfFe * m_PhytoPlanktonInf.m_dSi0 * m_PhytoPlanktonInf.m_TotalSelfMass[ll] * m_PhytoPlanktonInf.m_dVMax;

                    m_PhytoPlanktonInf.m_ReqCO2[ll] = (1.0/m_PhytoPlanktonInf.m_dKCO2) * m_PhytoPlanktonInf.m_TotalSelfMass[ll] * m_PhytoPlanktonInf.m_dVMax;

                    m_csOcnBacedlInf.m_TotalReqedPredationMass[ll] = m_csOcnBacedlInf.m_TotalSelfMass[ll] * 0.1;
                    m_csOcnBacedlInf.m_dCapturedMass[ll] = m_csOcnBacedlInf.m_TotalSelfMass[ll] * 0.1;
                }

            }
            return bRtn;
        }

        //=======================
        // 演算実行処理関連メソッド
        //=======================
        /// <summary>
        /// 受信
        /// </summary>
        protected override void ReceiveData()
        {
            ClearAllCalValue();

            // 養分吸収
            ReceiveFertilizer();
            
            // 捕食：動物プランクトン等からの要求量の取得
            ReceiveReqPREDATION();
            //ReceivePREDATION();

            // CO2吸収
            ReceiveCO2();
            
            return;
        }

        /// <summary>
        /// 送信例
        /// </summary>
        protected override void SendData()
        {
            // 養分吸収
            SendFertilizer();
            //被捕食
            SendPREDATION(m_csOcnBacedlInf.m_dCapturedMass, 0.1, 0.005);
            //SendReqPREDATION(m_csOcnBacedlInf.m_ReqFoodMass);

            // CO2吸収
            SendCO2();
            
            // 死
            SendEXCRETION_DEATH(m_csOcnBacedlInf.m_dExcretionDencity, m_csOcnBacedlInf.m_dBulkDensity);

            // Debug
            SendDEBUG();
            return;
        }

        protected virtual void ReceiveCO2()
        {
            // CO2吸収：
            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_PhytoPlanktonInf.m_lLayerNumber; ll++)
                    {
                        m_PhytoPlanktonInf.m_CO2[ll] += csCell[ll].m_dData[0];
                    }
                }
            }
        }
        protected virtual void SendCO2()
        {
            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_PhytoPlanktonInf.m_lLayerNumber; ll++)
                {
                    csSndDt[ll].m_dData[0] = m_PhytoPlanktonInf.m_O2Prduct[ll];
                    csSndDt[ll].m_dData[1] = m_PhytoPlanktonInf.m_ReqCO2[ll];
                }
            }
        }
        protected virtual void ReceiveFertilizer()
        {
            for (int i = 0; i < m_csRcvFertilizerCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csCell = m_csRcvFertilizerCnnct.m_csRcvInfArry[i].GetInterpolatedCellD1();
                if (csCell != null)
                {
                    for (int ll = 0; ll < m_PhytoPlanktonInf.m_lLayerNumber; ll++)
                    {
                        m_PhytoPlanktonInf.m_N[ll] += csCell[ll].m_dData[0];
                        m_PhytoPlanktonInf.m_P[ll] += csCell[ll].m_dData[1];
                        m_PhytoPlanktonInf.m_Si[ll] += csCell[ll].m_dData[2];
                        m_PhytoPlanktonInf.m_Fe[ll] += csCell[ll].m_dData[3];
                    }
                }
            }
        }
        protected virtual void SendFertilizer()
        {
            // 要求量を送信
            for (int i = 0; i < m_csRcvFertilizerCnnct.m_RcvInfNum; i++)
            {
                HySCellData[] csSndDt = m_csRcvFertilizerCnnct.m_csSndInfArry[i].PrepareSendCellD1();
                if (csSndDt == null) { break; }
                for (int ll = 0; ll < m_PhytoPlanktonInf.m_lLayerNumber; ll++)
                {
                    csSndDt[ll].m_dData[0] = m_PhytoPlanktonInf.m_ReqN[ll];
                    csSndDt[ll].m_dData[1] = m_PhytoPlanktonInf.m_ReqP[ll];
                    csSndDt[ll].m_dData[2] = m_PhytoPlanktonInf.m_ReqSi[ll];
                    csSndDt[ll].m_dData[3] = m_PhytoPlanktonInf.m_ReqFe[ll];
                }
            }
        }

        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_PhytoPlanktonInf.m_lLayerNumber; ll++)
                {
                    csCell[ll].m_dData[0] = m_PhytoPlanktonInf.m_TotalSelfMass[ll];
                    csCell[ll].m_dData[1] = m_PhytoPlanktonInf.m_CO2[ll];
                    csCell[ll].m_dData[2] = m_PhytoPlanktonInf.m_O2[ll];
                    csCell[ll].m_dData[3] = m_PhytoPlanktonInf.m_N[ll];
                    csCell[ll].m_dData[4] = m_PhytoPlanktonInf.m_P[ll];
                    csCell[ll].m_dData[5] = m_PhytoPlanktonInf.m_Si[ll];
                    csCell[ll].m_dData[6] = m_PhytoPlanktonInf.m_Fe[ll];
                }
            }
        }

        /// <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);
            // ①枯死
            Withered(dT);
            // ②成長
            GrowthModel(dT);

            // ③被捕食(被捕食者として)
            CalCapture();

            // ④死
            CalDeath();

            // 海水層モデルのデータ内に入れる（集計用）
            MzOceanAreaColumnModelCalInfo csColumInfo = this.GetOceanAreaColumnCalInfo();
            for (int ll = 0; ll < m_PhytoPlanktonInf.m_lLayerNumber; ll++)
            {
                csColumInfo.m_TotalSelfMass[ll] += m_PhytoPlanktonInf.m_TotalSelfMass[ll];
            }
            return 0;
        }

        /// <summary>
        /// 成長モデル
        /// </summary>
        protected virtual void GrowthModel(double dT)
        {
            MzOceanAreaColumnModelCalInfo csColumInfo = this.GetOceanAreaColumnCalInfo();

            double dLight = 1.0;
            double dMu1 = 1.0;
            double dMu4 = 1.0;
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                double dltMassMax = m_PhytoPlanktonInf.m_dVMax * m_csOcnBacedlInf.m_TotalSelfMass[ll] * dT;
                // 光制限
                {
                    //dLight = Light(csColumInfo.m_TotalEatenMass[ll], ll);
                    dLight = Light(csColumInfo.m_meanAllMass[ll], ll);
                    dMu1 = Steele(dLight, 1.0);
                    dltMassMax = dltMassMax * dMu1;
                }
                // 温度制限
                // 塩濃度制限
                // 栄養分制限
                {
                    // 窒素肥料分
                    dMu4 = Droop(m_csOcnBacedlInf.m_N[ll], m_PhytoPlanktonInf.m_dNmin, m_PhytoPlanktonInf.m_dN0);
                    // リン肥料分
                    dMu4 = dMu4 * Droop(m_csOcnBacedlInf.m_P[ll], m_PhytoPlanktonInf.m_dPmin, m_PhytoPlanktonInf.m_dP0);
                    // 鉄肥料分
                    dMu4 = dMu4 * Droop(m_csOcnBacedlInf.m_Fe[ll], m_PhytoPlanktonInf.m_dFemin, m_PhytoPlanktonInf.m_dFe0);
                    // シリカ肥料分
                    dMu4 = dMu4 * Droop(m_csOcnBacedlInf.m_Si[ll], m_PhytoPlanktonInf.m_dSimin, m_PhytoPlanktonInf.m_dSi0);
                }
                // 増殖分を加算する
                dltMassMax = dltMassMax * dMu4;
                m_csOcnBacedlInf.m_TotalSelfMass[ll] += dltMassMax;

                // 吸収したCO2の量
                m_csOcnBacedlInf.m_CO2[ll] -= dltMassMax * m_PhytoPlanktonInf.m_dKCO2;
                if (m_csOcnBacedlInf.m_CO2[ll] < 0.0) { m_csOcnBacedlInf.m_CO2[ll] = 0.0; }
                // 排出したO2の量
                m_PhytoPlanktonInf.m_O2Prduct[ll] = dltMassMax * m_PhytoPlanktonInf.m_dKO2;
                // 消費した栄養分の計算
                m_csOcnBacedlInf.m_N[ll] -= dltMassMax * m_PhytoPlanktonInf.m_dKfN;
                if (m_csOcnBacedlInf.m_N[ll] < 0.0) { m_csOcnBacedlInf.m_N[ll] = 0.0; }
                m_csOcnBacedlInf.m_P[ll] -= dltMassMax * m_PhytoPlanktonInf.m_dKfP;
                if (m_csOcnBacedlInf.m_P[ll] < 0.0) { m_csOcnBacedlInf.m_P[ll] = 0.0; }
                m_csOcnBacedlInf.m_Fe[ll] -= dltMassMax * m_PhytoPlanktonInf.m_dKfSi;
                if (m_csOcnBacedlInf.m_Fe[ll] < 0.0) { m_csOcnBacedlInf.m_Fe[ll] = 0.0; }
                m_csOcnBacedlInf.m_Si[ll] -= dltMassMax * m_PhytoPlanktonInf.m_dKfFe;
                if (m_csOcnBacedlInf.m_Si[ll] < 0.0) { m_csOcnBacedlInf.m_Si[ll] = 0.0; }

                double dNxtMass = m_PhytoPlanktonInf.m_dVMax * m_csOcnBacedlInf.m_TotalSelfMass[ll] * dT;
                // 要求量を計算
                m_PhytoPlanktonInf.m_ReqN[ll] = dNxtMass * m_PhytoPlanktonInf.m_dKfN * (m_PhytoPlanktonInf.m_dN0 / m_PhytoPlanktonInf.m_dNmin); //+ m_PhytoPlanktonInf.m_dNmin;
                m_PhytoPlanktonInf.m_ReqP[ll] = dNxtMass * m_PhytoPlanktonInf.m_dKfP * (m_PhytoPlanktonInf.m_dP0 / m_PhytoPlanktonInf.m_dPmin);  //+ m_PhytoPlanktonInf.m_dPmin;
                m_PhytoPlanktonInf.m_ReqSi[ll] = dNxtMass * m_PhytoPlanktonInf.m_dKfSi * (m_PhytoPlanktonInf.m_dFe0 / m_PhytoPlanktonInf.m_dFemin);  //+ m_PhytoPlanktonInf.m_dFemin;
                m_PhytoPlanktonInf.m_ReqFe[ll] = dNxtMass * m_PhytoPlanktonInf.m_dKfFe * (m_PhytoPlanktonInf.m_dSi0 / m_PhytoPlanktonInf.m_dSimin);  //+ m_PhytoPlanktonInf.m_dSimin;

                m_PhytoPlanktonInf.m_ReqCO2[ll] = dNxtMass * m_PhytoPlanktonInf.m_dKCO2;

            }
        }

        /// <summary>
        /// 枯死　　Q2呼吸による内部Mass（量が）一定以下となったものが、死亡する　＝
        /// </summary>
        protected virtual void Withered(double dT)
        {
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                double dltMass = m_PhytoPlanktonInf.d_KConsume * m_csOcnBacedlInf.m_TotalSelfMass[ll] * dT;

                // 一定量が枯渇による死亡
                m_csOcnBacedlInf.m_Death[ll] += dltMass * m_PhytoPlanktonInf.d_KWithered;

                // 死亡しない方は体重が減り、死亡したものは取り除かれる
                m_csOcnBacedlInf.m_TotalSelfMass[ll] -= dltMass; // * (1.0 -m_PhytoPlanktonInf.d_KDetritus +  m_PhytoPlanktonInf.d_KDetritus); 
                if (m_csOcnBacedlInf.m_TotalSelfMass[ll] < 0.0) { m_csOcnBacedlInf.m_TotalSelfMass[ll] = 0.0; }
                // 吸収したO2の量
                m_csOcnBacedlInf.m_O2[ll] -= dltMass * (1.0 - m_PhytoPlanktonInf.d_KWithered) * m_PhytoPlanktonInf.d_AbsO2;
                if (m_csOcnBacedlInf.m_O2[ll] < 0.0) { m_csOcnBacedlInf.m_O2[ll] = 0.0; }
                // 排出したCO2の量
                m_csOcnBacedlInf.m_CO2[ll] += dltMass * (1.0 - m_PhytoPlanktonInf.d_KWithered) * m_PhytoPlanktonInf.d_AbsCO2;
            }
        }

        protected override void CalDeath()
        {
            double dDeathRatio = m_csOcnBacedlInf.m_dDeathRatio;
            double dDeathMass = 0.0;
            for (int ll = 0; ll < m_csOcnBacedlInf.m_lLayerNumber; ll++)
            {
                dDeathMass = m_csOcnBacedlInf.m_TotalSelfMass[ll] * dDeathRatio;
                m_csOcnBacedlInf.m_Death[ll] += dDeathMass;
                m_csOcnBacedlInf.m_TotalSelfMass[ll] -= dDeathMass;
                if (m_csOcnBacedlInf.m_TotalSelfMass[ll] < 0.0) { m_csOcnBacedlInf.m_TotalSelfMass[ll] = 0.0; }

                //// 密度が大きくなった場合の自然死
                //dDeathMass = m_csOcnBacedlInf.m_TotalSelfMass[ll] * ( 1.0 - 20000/(20000 + m_csOcnBacedlInf.m_TotalSelfMass[ll]));
                //m_csOcnBacedlInf.m_Death[ll] += dDeathMass;
                //m_csOcnBacedlInf.m_TotalSelfMass[ll] -= dDeathMass;
            }
        }
    
        //====================
        // その他必要なメソッド
        //====================

        /// <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)
        {
            bool bRtn = base.SetProperty(csCellMdlPropertyInfo);

            // 使用しやすいようにキャストしておく
            //m_PhytoPlanktonInf = csCellMdlPropertyInfo as MzOceanPhytoplanktonsCalInfo;
            m_PhytoPlanktonInf = (MzOceanPhytoplanktonsCalInfo)m_csCalInfo;
            ////McOceanBaseDefine.PHYTOPLANKTONS_KIND)
            m_PhytoPlanktonInf.m_ReqN = new double[m_csOcnBacedlInf.m_lLayerNumber];
            m_PhytoPlanktonInf.m_ReqP = new double[m_csOcnBacedlInf.m_lLayerNumber];
            m_PhytoPlanktonInf.m_ReqSi = new double[m_csOcnBacedlInf.m_lLayerNumber];
            m_PhytoPlanktonInf.m_ReqFe = new double[m_csOcnBacedlInf.m_lLayerNumber];

            for(int ll=0;ll< m_csOcnBacedlInf.m_lLayerNumber;ll++)
            {
                m_PhytoPlanktonInf.m_ReqN[ll] = 0.0;
                m_PhytoPlanktonInf.m_ReqP[ll] = 0.0;
                m_PhytoPlanktonInf.m_ReqSi[ll] = 0.0;
                m_PhytoPlanktonInf.m_ReqFe[ll] = 0.0;
            }

            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
                this.SetDeath(ref csPrptyInfo);

                csPrptyInfo.GetInfo("m_dSelfSize", ref m_PhytoPlanktonInf.m_dSelfSize);
                csPrptyInfo.GetInfo("m_dSelfWeight", ref m_PhytoPlanktonInf.m_dSelfWeight);
                csPrptyInfo.GetInfo("m_dBulkDensity", ref m_PhytoPlanktonInf.m_dBulkDensity);
 
                csPrptyInfo.GetInfo("m_CapturedRatio", ref m_PhytoPlanktonInf.m_CapturedRatio);
 
                csPrptyInfo.GetInfo("m_dVMax", ref m_PhytoPlanktonInf.m_dVMax);

                csPrptyInfo.GetInfo("m_dN0", ref m_PhytoPlanktonInf.m_dP0);
                csPrptyInfo.GetInfo("m_dNmin", ref m_PhytoPlanktonInf.m_dNmin);
                csPrptyInfo.GetInfo("m_dP0", ref m_PhytoPlanktonInf.m_dP0);
                csPrptyInfo.GetInfo("m_dPmin", ref m_PhytoPlanktonInf.m_dPmin);
                csPrptyInfo.GetInfo("m_dFe0", ref m_PhytoPlanktonInf.m_dP0);
                csPrptyInfo.GetInfo("m_dFemin", ref m_PhytoPlanktonInf.m_dFemin);
                csPrptyInfo.GetInfo("m_dSi0", ref m_PhytoPlanktonInf.m_dP0);
                csPrptyInfo.GetInfo("m_dSimin", ref m_PhytoPlanktonInf.m_dSimin);

                csPrptyInfo.GetInfo("m_dKCO2", ref m_PhytoPlanktonInf.m_dKCO2);
                csPrptyInfo.GetInfo("m_dKO2", ref m_PhytoPlanktonInf.m_dKO2);
                csPrptyInfo.GetInfo("m_dKfN", ref m_PhytoPlanktonInf.m_dKfN);
                csPrptyInfo.GetInfo("m_dKfP", ref m_PhytoPlanktonInf.m_dKfP);
                csPrptyInfo.GetInfo("m_dKfSi", ref m_PhytoPlanktonInf.m_dKfSi);
                csPrptyInfo.GetInfo("m_dKfFe", ref m_PhytoPlanktonInf.m_dKfFe);

                csPrptyInfo.GetInfo("d_AbsO2", ref m_PhytoPlanktonInf.d_AbsO2);
                csPrptyInfo.GetInfo("d_AbsCO2", ref m_PhytoPlanktonInf.d_AbsCO2);
                csPrptyInfo.GetInfo("d_KConsume", ref m_PhytoPlanktonInf.d_KConsume);
                csPrptyInfo.GetInfo("d_KDetritus", ref m_PhytoPlanktonInf.d_KWithered);

                double dltT = m_csDltTime.TotalSec();
                double n = dltT / (24 * 3600);
                m_PhytoPlanktonInf.m_CapturedRatio = 1.0 - Math.Pow((1.0 - m_PhytoPlanktonInf.m_CapturedRatio), n);
                m_PhytoPlanktonInf.m_dDeathRatio = 1.0 - Math.Pow((1.0 - m_PhytoPlanktonInf.m_dDeathRatio), n);

                m_PhytoPlanktonInf.m_dMetabolismK = 1.0 - Math.Pow((1.0 - m_PhytoPlanktonInf.m_dMetabolismK), n);
            }

            return true;
        }

    }
}
