蛇島伸吾メール蛇島伸吾     (前頁)<<      >>(次頁)          (Up)

4章  要素モデル自作の方法
 4.7  「海中溶融ガス」要素モデルと「大気圏」要素モデル
     〜 海洋モデル用要素モデルの作成例(サンプルプロジェクトプレジェクト:McOceanSampleModels.csproj 」)  〜



 「海中溶融ガス」要素モデルは海中に溶け込んでいるO2、CO2等のガスの量を管理し、海中の植物プランクトンや、その他の生物等の要素モデルと接続し、呼吸や光合成で必要なガス、排ガスを供給、吸収します。
 「大気圏」は(海洋開発に関する活動に限る)人間活動に伴うO2吸収量と、CO2排出量を累積すると共に、海面を通して海水へのCO2吸収、O2の排出等を行います。

   (大気圏へのCO2放出量) = (海洋面からのCO2放出量) + Σ(遠海洋開発関連事業に関連する人間活動から大気圏に排出されるCO2量)

 この為、上記式での 大気圏へのCO2放出量がマイナスの場合には 海上施肥による大気圏からのCO2吸収が上手く機能している事になります。

    
 海水中へのCO2吸収とその管理要素クラス
  図4.7.1 「海中溶融ガス」要素モデルと「大気圏要素モデル」の接続
   海中内の生物等は全て「海中溶融ガス」要素モデルに接続されて、呼吸や光合成で必要・排出するガスを取得する。
   一方、海上では、人間活動は全て大気圏に接続されてO2の消費・CO2の排出を管理している。
   海洋と大気間のガスの交換は「海中溶融ガス」要素モデルと「大気圏」要素モデルの間の接続を通じて行う。


 「海中溶融ガス」要素モデルと、「大気圏」要素モデルも、他の要素モデルと同様にファクトリークラスを使用して生成します。(ソースコード4.7.1参照)

ソースコード:4.7.1  ファクトリクラスでの関連クラス生成

namespace CommonMP.HYMCO.Ocean.McOceanSampleModels
{
    public class MzOceanSmplFactory : McBasicModelFactoryBase  // MzOceanModelBaseFactory
    {
        /// <para>演算モデルクラス生成</para>
        public override McCalModel CreateCalModel(HySObjectKind csModelKind)
        {
            McCalModel csCalModel = null;< /FONT >

            if (csModelKind == MzOceanBaseDefine.NEKTONS_KIND)
            {
                ……………
            }
            else if (csModelKind == MzOceanBaseDefine.DISSOLVE_GAS_KIND )
            {
                csCalModel = new MzOceanDissolveGass ( );
            }
            //else if (csModelKind == MzOceanBaseDefine.ATMOSPHERE_KIND )
            //{
            //    <-- 本クラスは McOceanBaseModel.dll 側で生成する為、ここでは生成しない
            //    MzOceanAtmosphere OceanAtmosphereModel = new MzOceanAtmosphere< /STRONG > ();
            //    MzOceanModelElement.OceanAtmosphereModel = OceanAtmosphereModel;
            //    csCalModel = OceanAtmosphereModel;
            //}
           
            ………………

            return csCalModel;
        }

        /// <para>要素内演算中データクラス生成</para>
        public override McCalInfo CreateCalInfo(HySObjectKind csModelKind)
        {
            McCalInfo csCalInfoData = null;< /FONT >

            if (csModelKind == MzOceanBaseDefine.NEKTONS_KIND)
            {
                ……………
            }
            else if (csModelKind ==
MzOceanBaseDefine.DISSOLVE_GAS_KIND )
            {
                csCalInfoData = new MzOceanDissolveGassCalInfo ( );
            }
            //else if (csModelKind ==
MzOceanBaseDefine.ATMOSPHERE_KIND )
            //{
            //    <-- 本クラスは McOceanBaseModel.dll 側で生成する為、ここでは生成しない
            //    csCalInfoData = new MzOceanAtmosphereCalInfo ( );
            //}
            ………………
            return csCalInfoData;
        }

        /// <para>モデルプロパティ表示/設定情報クラス生成</para>
        public override McCellModelPropertyIF CreateModelProperty(HySID csLibraryID, HySObjectKind csModelKind)
        {
            McCellModelPropertyInfo csRtnCellPrptyDt = new McCellModelPropertyInfo(csLibraryID, csModelKind);
            ………………

            if (csModelKind == MzOceanBaseDefine.OCEAN_COLUMN_KIND)
            {   // 海洋の層 (Ocean layer)クラス
                ……………
            }
            else if (csModelKind ==
MzOceanBaseDefine.DISSOLVE_GAS_KIND )
            {   // 溶融ガス(Gas)クラス

                csRtnCellPrptyDt.AddInfoType("O2_L0", "真光層へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L0", 1.0);
                csRtnCellPrptyDt.AddInfoType("O2_L1", "透光層へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L1", 0.01E-2);
                csRtnCellPrptyDt.AddInfoType("O2_L2", "中深層へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L2", 0.01E-2);
                csRtnCellPrptyDt.AddInfoType("O2_L3", "漸深層へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L3", 0.025E-1);
                csRtnCellPrptyDt.AddInfoType("O2_L4", "深海層へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L4", 0.05E-1);
                csRtnCellPrptyDt.AddInfoType("O2_L5", "海底へのO2流れ込み:海洋ベルトコンベア等で運ばれてくるO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("O2_L5", 0.025E-2);

                csRtnCellPrptyDt.AddInfoType("CO2_L0", "真光層へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("CO2_L0", 1.0);
                csRtnCellPrptyDt.AddInfoType("CO2_L1", "透光層へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("CO2_L1", 0.01E-2);
                csRtnCellPrptyDt.AddInfoType("CO2_L2", "中深層へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("CO2_L2", 0.01E-2);
                csRtnCellPrptyDt.AddInfoType("CO2_L3", "漸深層へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("OC2_L3", 0.025E-1);
                csRtnCellPrptyDt.AddInfoType("CO2_L4", "深海層へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("CO2_L4", 0.05E-1);
                csRtnCellPrptyDt.AddInfoType("CO2_L5", "海底へのCO2流れ込み:海洋ベルトコンベア等で運び出されるCO2の量", McDefine.ValKind.DOUBLE);
                csRtnCellPrptyDt.SetInfo("CO2_L5", 0.025E-2);

                // 層設定
                this.SetLayer(ref csRtnCellPrptyDt, 7, 6000); //, 10 * 10);

                // 受信可能なパターンの設定
                {
                    //  大気からの溶け込み
                    McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(
MzOceanBaseDefine.GASS_DISSOLVE< /FONT > , csModelKind);
                    csRtnCellPrptyDt.AddReceivePattern (csTrnPtn);  // 受信可能パターンの追加
                }
                // 送信パターンの設定
                {
                    // 光合成によるCO2吸収
                    McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(
MzOceanBaseDefine.CO2_ABSORPTION< /FONT > , csModelKind);
                    csRtnCellPrptyDt.AddSendPattern (csTrnPtn);  // 送信可能パターンの追加

                    // 呼吸
                    csTrnPtn = MzFlowObjBaseFactory.CreateFlow(
MzOceanBaseDefine.BREATHING< /FONT > , csModelKind);
                    csRtnCellPrptyDt.AddSendPattern (csTrnPtn);  // 受信可能パターンの追加

                }
            }
            //----------------
            //else if (csModelKind ==
MzOceanBaseDefine.ATMOSPHERE_KIND )
            //{   // 大気圏(atmosphere)クラス
            //    <-- 本クラスは McOceanBaseModel.dll 側で生成する為、ここでは生成しない
            //    // 層設定
            //    this.SetLayer(ref csRtnCellPrptyDt, 7, 6000); //, 10 * 10);
            //    // 受信 可能なパターン
            //    {
            //        // 人間の行為によるCO2排出量
            //        McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(
MzOceanBaseDefine.CO2_EMISSION< /FONT > , csModelKind);
            //        csRtnCellPrptyDt.AddReceivePattern (csTrnPtn);  // 受信可能パターンの追加
            //    }
            //    // 送信 パターンの設定
            //    {
            //        //  大気からの溶け込み
            //        McTranInfoPattern csTrnPtn = MzFlowObjBaseFactory.CreateFlow(
MzOceanBaseDefine.GASS_DISSOLVE< /FONT > , csModelKind);
            //        csRtnCellPrptyDt.AddSendPattern (csTrnPtn); 
      //
            //        // CO2調査
            //        csTrnPtn = MzFlowObjBaseFactory.CreateFlow(MzOceanBaseDefine.RESEARCH_CO2_ABSORPTION, csModelKind);
            //        csRtnCellPrptyDt.AddSendPattern(csTrnPtn);
            //    }
            //}
            ………………

            return csRtnCellPrptyDt;
        }

        /// <para>モデル初期化表示/設定情報生成</para>
        public override McPropertyInfoRoot CreateModelInitialInfo(HySID csLibraryID, HySObjectKind csModelKind)
        {
            if (this.EqualFactory(csLibraryID) == false)
            {
                return null;
            }

            McInitialInfo csRtnDt = new McInitialInfo(csLibraryID, csModelKind);< /FONT >

            if (csModelKind == MzOceanBaseDefine.OCEAN_COLUMN_KIND)
            {
                ……………
            }
            else if (csModelKind ==
MzOceanBaseDefine.DISSOLVE_GAS_KIND )
            {   // 溶融ガス(Gas)クラス
                csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
                csRtnDt.AddInfoType("O2_TotalMass_L0", "海面表層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L0", 8.11);
                csRtnDt.AddInfoType("O2_TotalMass_L1", "真光層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L1", 2.0);
                csRtnDt.AddInfoType("O2_TotalMass_L2", "透光層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L2", 5.0);
                csRtnDt.AddInfoType("O2_TotalMass_L3", "中深層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L3", 5.0);
                csRtnDt.AddInfoType("O2_TotalMass_L4", "漸深層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L4", 6.0);
                csRtnDt.AddInfoType("O2_TotalMass_L5", "深海層:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L5", 6.0);
                csRtnDt.AddInfoType("O2_TotalMass_L6", "海底:O2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("O2_TotalMass_L6", 6.0);

                csRtnDt.AddInfoType("CO2_TotalMass_L0", "海面表層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L0", 1.452);
                csRtnDt.AddInfoType("CO2_TotalMass_L1", "真光層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L1", 2.0);
                csRtnDt.AddInfoType("CO2_TotalMass_L2", "透光層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L2", 3.0);
                csRtnDt.AddInfoType("CO2_TotalMass_L3", "中深層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L3", 3.0);
                csRtnDt.AddInfoType("CO2_TotalMass_L4", "漸深層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L4", 4.0);
                csRtnDt.AddInfoType("CO2_TotalMass_L5", "深海層:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L5", 4.0);
                csRtnDt.AddInfoType("CO2_TotalMass_L6", "海底:CO2_初期存在量[g/m3]", McDefine.ValKind.DOUBLE);
                csRtnDt.SetInfo("CO2_TotalMass_L6", 4.0);

            }
            //----------------
            //else if (csModelKind ==
MzOceanBaseDefine.ATMOSPHERE_KIND )
            //{
            //    <-- 本クラスは McOceanBaseModel.dll 側で生成する為、ここでは生成しない
            //    csRtnDt = new McInitialInfo(csLibraryID, csModelKind);
            //}
            ………………
            return csRtnDt;
        }

        /// <para>モデル情報提供</para>
        public override HySDataLinkedList GetCalModelInfoList()
        {
            McModelInfo csModelInfo = null;< /FONT >

            ………………
            //--
            csModelInfo = new McModelInfo(
                    (HySID)this.GetFactoryID(),
                    McModelLibraryDefine.DIVISION_CALCULATION_MODEL, // <-- 演算モデルは、必ずこの値にして下さい(LibraryCategoryXML.xmlに記述されている)
                    new HySObjectKind("CAL_OCEAN_MODELS"), // LibraryCategoryXML.xmlに記述されている <Category>タグ内のIDに対応します。
                    MzOceanBaseDefine.DISSOLVE_GAS_KIND , // モデルの識別子
                    MzOceanBaseDefine.DISSOLVE_GAS_NAME   // モデルの名称
                                          );
            csModelInfo.SetVersionInf("Ver1.0 ");
            csModelInfo.SetSummaryInf("溶融ガス(主にO2,CO2)");
            csModelInfo.SetCreatorInf("S.H.");
            csModelInfo.SetIconName(@"Ocean\dissolveGas");
            csModelInfo.SetManualFileName(@".\Ocean\SampleModelExplanation.pdf"); // <-- モデル解説書

            m_csCalModelInforList.AddLast(csModelInfo);

            //--

            ////--
            //    <-- 本クラスは McOceanBaseModel.dll 側で生成する為、ここでは生成しない
            //csModelInfo = new McModelInfo(
            //        (HySID)this.GetFactoryID(),
            //        McModelLibraryDefine.DIVISION_CALCULATION_MODEL, // <-- 演算モデルは、必ずこの値にして下さい(LibraryCategoryXML.xmlに記述されている)
            //        new HySObjectKind("CAL_OCEAN_MODELS"), // LibraryCategoryXML.xmlに記述されている <Category>タグ内のIDに対応します。
            //        MzOceanBaseDefine.ATMOSPHERE_KIND , // モデルの識別子
            //        MzOceanBaseDefine.ATMOSPHERE_NAME   // モデルの名称
            //                              );
            //csModelInfo.SetVersionInf("Ver1.0 ");
            //csModelInfo.SetSummaryInf("大気圏(atmosphere)  ");
            //csModelInfo.SetCreatorInf("S.H.");
            //csModelInfo.SetIconName(@"Ocean\Atmosphere");
            //csModelInfo.SetManualFileName(@".\Ocean\SampleModelExplanation.pdf"); // <-- モデル解説書
            //m_csCalModelInforList.AddLast(csModelInfo);

            ………………

            return m_csCalModelInforList;
        }
    }
} 


ソースコード:4.7.2  「海中溶融ガス」要素モデルの 送受信関係端子変数の設定

// 溶融ガス要素クラス
public class MzOceanDissolveGass : MzOceanModelElement
{
        // 呼吸関係: McOceanBaseDefine.BREATHING
        protected McPatternRdvSndTranInfoPair m_csRcvBreathingCnnct = new McPatternRdvSndTranInfoPair();     // <-- 使用せず
        protected McPatternRdvSndTranInfoPair m_csSndBreathingCnnct = new McPatternRdvSndTranInfoPair();

        // 光合成CO2吸収: 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();     // <-- 使用せず

        /// </remarks>
        protected override bool CheckReceiveDataConnection(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
             // 呼吸関係   m_csRcvBreathingCnnctは使用せず
            (m_csRcvBreathingCnnct, m_csSndBreathingCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.BREATHING);

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

            // 大気からのガス溶融   m_csSndDmyCnnctは使用せず
            (m_csRcvGassDissolveCnnct, m_csSndDmyCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.GASS_DISSOLVE);
       
            return bRtn;
        }
          ………………

 
ソースコード:4.7.3  「大気圏ガス」要素モデルの 送受信関係端子変数の設定

// 大気圏ガス
public class MzOceanAtmosphere : MzOceanModelElement
{
    // CO2排出: McOceanBaseDefine.CO2_EMISSION
    protected McPatternRdvSndTranInfoPair m_csRcvCO2EmissionCnnct = new McPatternRdvSndTranInfoPair();
    protected McPatternRdvSndTranInfoPair m_csSndCO2DmyCnnct = new McPatternRdvSndTranInfoPair();    // <-- 使用せず

    // ガスの溶融・放出: McOceanBaseDefine.GASS_DISSOLVE
    protected McPatternRdvSndTranInfoPair m_csRcvDmyCnnct = new McPatternRdvSndTranInfoPair();    // <-- 使用せず
    protected McPatternRdvSndTranInfoPair m_csSndGassDissolveCnnct = new McPatternRdvSndTranInfoPair();

    // CO2調査
    protected McPatternRdvSndTranInfoPair m_csSndResearchCO2Cnnct = new McPatternRdvSndTranInfoPair();

    /// <para>入力側の接続情報チェック</para>
    protected override bool CheckReceiveDataConnection(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
    {
        // CO2排出   m_csSndCO2DmyCnnctは使用せず
        (m_csRcvCO2EmissionCnnct, m_csSndCO2DmyCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.CO2_EMISSION);

        // 海水への各種気体溶け込み  m_csRcvDmyCnnct,は使用せず
        (m_csRcvDmyCnnct, m_csSndGassDissolveCnnct) = this.PrepareRcvSndPattern(MzOceanBaseDefine.GASS_DISSOLVE);

        // CO2吸収量送信
        m_csSndResearchCO2Cnnct = this.PrepareSndPattern(MzOceanBaseDefine.RESEARCH_CO2_ABSORPTION);
      
        return bRtn;
    }





海中溶融ガス」要素モデルは下記のような動作を行います。
      モデル全体構造作成を優先していますので、ここの論理は不正確です。後ほど修正していく予定です。(知識のある方は、要素モデルを自作して、本サンプルと交換してください。)

1)現在の酸素の量と要求された酸素の総和から提供可能な酸素量を計算する。
  (複数に要求された場合には、各要求もとへの分配は 「csSndBreathingCnnct」が行う )
ソースコード:4.7.4
            // 提供可能なO2量計算  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];
            }

2)現在の二酸化炭素の量と要求された酸素の総和から提供可能な二酸化炭素量を計算する。
  (複数に要求された場合には、各要求もとへの分配は 「csSndPhytoCO2Cnnct 」が行う )
ソースコード:4.7.5
            // 提供可能なCO2量計算  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];
            } 

3)海水から大気圏へ放出されるガス量を計算する。
ソースコード:4.7.6

            double dT = m_csDltTime.GetTime() / (3600.0 * 24.0);  // 時間
    
            // 表面上のO2,CO2量
            m_OcLyrMdlInf.m_SurfaceO2 = m_OcLyrMdlInf.m_O2[0];
            m_OcLyrMdlInf.m_SurfaceCO2 = m_OcLyrMdlInf.m_CO2[0];

            // 大気の溶け込み処理そのものは ReceiveGassDissolve()内で行う
            // 大気へ放出する気体の計算
            //   MzOceanDissolveGassCalInfo.S_O2: 海面上の酸素分圧、MzOceanDissolveGassCalInfo.S_CO2:海面上のCO2分圧
            //   水中の分圧が高い時は放出する 
            // ***海水から大気圏への放出のみを計算する為、必ず+とする。==>そのまま送信する。
            // ***大気圏から海水への吸収は、McOceanAtmosphere(大気圏)側が計算して、その値を受信する。
            m_OcLyrMdlInf.m_Emission_O2 = dT * (m_OcLyrMdlInf.m_SurfaceO2 - MzOceanDissolveGassCalInfo.S_O2);
            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);
            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;
            // 大気圏への排出 計算後 表層のO2,CO2量を補正しておく


4)上下の層で気体の拡散を行う。

5)海洋ベルトコンベアーで運ばれて多少のO2、CO2の入出力があるとする
ソースコード:4.7.7

            // 海洋ベルトコンベア等で運ばれてくる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]; 




大気圏」要素モデルは下記のような動作を行います。
     *ここの論理は不正確なため後で色々と修正していきます。(モデル全体構造作成を優先しています。知識のある方は、要素モデルを自作して本サンプルと交換してください)

1)人間活動から要求されたO2は要求通り提供するとする。
  また、人間活動から排出されたCO2はそのままとする(単位体積中に累積はしない。但し、累積計算の為には用いる。)

2)大気圏から海水中に吸収されるガスの計算を行う。
ソースコード:4.7.8

            double dT = m_csDltTime.GetTime() / (3600.0 * 24.0);    // 時間
 
            // 海水へのガス溶け込み
            //   MzOceanDissolveGassCalInfo.S_O2: 海面上の酸素分圧、MzOceanDissolveGassCalInfo.S_CO2:海面上のCO2分圧 
            //   水中の分圧が高い時は放出する === m_OcLyrMdlInf.m_O2inSea  水中のO2圧、  m_OcLyrMdlInf.m_CO2inSea  水中のCO2圧
            // ***大気圏から海水への吸収のみを計算する為、必ず+とする。==>そのまま送信する。
            // ***海水から大気圏への放出は、McOceanDissolveGass(溶融ガス)側が計算して、その値を受信する。
            m_OcLyrMdlInf.m_Dissolve_O2intoSea = dT * (MzOceanAtmosphereCalInfo.S_O2 - m_OcLyrMdlInf.m_O2inSea);  // 溶融ガス量計算
            if (m_OcLyrMdlInf.m_Dissolve_O2intoSea < 0.0) { m_OcLyrMdlInf.m_Dissolve_O2intoSea = 0.0; }
            m_OcLyrMdlInf.m_Dissolve_CO2intoSea = dT * (MzOceanAtmosphereCalInfo.S_CO2 - m_OcLyrMdlInf.m_CO2inSea);   // 溶融ガス量計算
            if (m_OcLyrMdlInf.m_Dissolve_CO2intoSea < 0.0) { m_OcLyrMdlInf.m_Dissolve_CO2intoSea = 0.0; }
      



<テスト>
 制作した栄養成分モデルのテストを行います。
     (*注意) :ユニットテストは別途おこないますが、ここではユニットテストの記述は省きます。
  
 
 大気圏中の二酸化炭素を海水が吸収するシミュレーション
  図4.7.2 海中の「溶融ガス」要素モデル と 「大気圏」要素モデルを接続した場合のテスト

 二酸化炭素の海水への吸収シミュレーション結果
  図4.7.3 大気圏から海水に吸収されるCO2の推移と、植物プランクトンの増減
         (海上施肥の間隔が7日の為、植物プランクトンも7日周期で増減を繰り返している。
          大気圏から海水へ吸収されるCO2の量は 植物プランクトンの増減に一致している。)

  
 海上施肥の間隔を7日間隔で行うと、それに伴って海面の植物プランクトンの数も増減しています。植物プランクトンが吸収するCO2の量もそれに応じて変化する為、大気圏から海水へ吸収されるCO2の量もそれに応じて変動しています。

次頁では、「海洋施肥」要素モデルの制作を行います。

 


(前頁)<<      >>(次頁)

初版:2022/07/19 |