コード例 #1
0
        //---------------------------------------------------------------------
        public void DecomposeMetabolic(ActiveSite site)
        {
            double litterC = this.Carbon;
            double anerb   = SiteVars.AnaerobicEffect[site];

            if (litterC > 0.0000001)
            {
                // Determine C/N ratios for flows to SOM1
                double ratioCNtoSOM1 = 0.0;
                double co2loss       = 0.0;

                // Compute ratios for surface  metabolic residue
                if (this.Type == LayerType.Surface)
                {
                    ratioCNtoSOM1 = Layer.AbovegroundDecompositionRatio(this.Nitrogen, litterC);
                }

                //Compute ratios for soil metabolic residue
                else
                {
                    ratioCNtoSOM1 = Layer.BelowgroundDecompositionRatio(site,
                                                                        OtherData.MinCNenterSOM1,
                                                                        OtherData.MaxCNenterSOM1,
                                                                        OtherData.MinContentN_SOM1);
                }

                //Compute total C flow out of metabolic layer
                double totalCFlow = litterC
                                    * SiteVars.DecayFactor[site]
                                    * OtherData.LitterParameters[(int)this.Type].DecayRateMetabolicC
                                    * OtherData.MonthAdjust;

                //PlugIn.ModelCore.UI.WriteLine("DecomposeMeta1.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                //Added impact of soil anerobic conditions
                if (this.Type == LayerType.Soil)
                {
                    totalCFlow *= anerb;
                }

                //Make sure metabolic C does not go negative.
                if (totalCFlow > litterC)
                {
                    totalCFlow = litterC;
                }

                //If decomposition can occur,
                if (this.DecomposePossible(ratioCNtoSOM1, SiteVars.MineralN[site]))
                {
                    //CO2 loss
                    if (this.Type == LayerType.Surface)
                    {
                        co2loss = totalCFlow * OtherData.MetabolicToCO2Surface;
                    }
                    else
                    {
                        co2loss = totalCFlow * OtherData.MetabolicToCO2Soil;
                    }

                    //PlugIn.ModelCore.UI.WriteLine("BeforeResp.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                    this.Respiration(co2loss, site);
                    //PlugIn.ModelCore.UI.WriteLine("AfterResp.  MineralN={0:0.00}.", SiteVars.MineralN[site]);

                    //Decompose metabolic into som1
                    double netCFlow = totalCFlow - co2loss;

                    if (netCFlow > litterC)
                    {
                        PlugIn.ModelCore.UI.WriteLine("   ERROR:  Decompose Metabolic:  netCFlow={0:0.000} > layer.Carbon={0:0.000}.", netCFlow, this.Carbon);
                    }

                    // -- CARBON AND NITROGEN ---------------------------
                    // Partition and schedule C flows
                    // Compute and schedule N flows and update mineralization accumulators.
                    if ((int)this.Type == (int)LayerType.Surface)
                    {
                        this.TransferCarbon(SiteVars.SOM1surface[site], netCFlow);
                        this.TransferNitrogen(SiteVars.SOM1surface[site], netCFlow, litterC, ratioCNtoSOM1, site);
                        //PlugIn.ModelCore.UI.WriteLine("DecomposeMetabolic.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                    }
                    else
                    {
                        this.TransferCarbon(SiteVars.SOM1soil[site], netCFlow);
                        this.TransferNitrogen(SiteVars.SOM1soil[site], netCFlow, litterC, ratioCNtoSOM1, site);
                    }
                }
            }
            //}
        }
コード例 #2
0
        public static void Decompose(ActiveSite site)
        {
            //PlugIn.ModelCore.UI.WriteLine("SiteVars.SOM2[site].Nitrogen = {0:0.00}", SiteVars.SOM2[site].Nitrogen);
            //PlugIn.ModelCore.UI.WriteLine("SiteVars.MineralN = {0:0.00}", SiteVars.MineralN[site]);

            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];

            //---------------------------------------------------------------------
            // Surface SOM1 decomposes to SOM2 with CO2 lost to respiration.

            double som1c_surface = SiteVars.SOM1surface[site].Carbon;

            if (som1c_surface > 0.0000001)
            {
                // Determine C/N ratios for flows to som2
                double radds1 = OtherData.SurfaceActivePoolCNIntercept
                                + OtherData.SurfaceActivePoolCNSlope * ((som1c_surface / SiteVars.SOM1surface[site].Nitrogen)
                                                                        - OtherData.MinCNSurfMicrobes);

                double ratioCNtoSOM2 = (som1c_surface / SiteVars.SOM1surface[site].Nitrogen) + radds1;
                ratioCNtoSOM2 = System.Math.Max(ratioCNtoSOM2, OtherData.SurfaceActivePoolCNMinimum);

                //Compute total C flow out of surface microbes.
                double totalCflow = som1c_surface
                                    * SiteVars.DecayFactor[site]
                                    * EcoregionData.DecayRateSurf[ecoregion]
                                    * OtherData.MonthAdjust
                                    * OtherData.LitterParameters[(int)LayerType.Surface].DecayRateMicrobes;

                // If decomposition can occur, schedule flows associated with respiration
                // and decomposition
                if (SiteVars.SOM1surface[site].DecomposePossible(ratioCNtoSOM2, SiteVars.MineralN[site]))
                {
                    //CO2 loss - Compute and schedule respiration flows.
                    double co2loss  = totalCflow * OtherData.P1CO2_Surface;
                    double netCFlow = totalCflow - co2loss;
                    SiteVars.SOM1surface[site].Respiration(co2loss, site);

                    // Decompose Surface SOM1 to SOM2
                    SiteVars.SOM1surface[site].TransferCarbon(SiteVars.SOM2[site], netCFlow);
                    SiteVars.SOM1surface[site].TransferNitrogen(SiteVars.SOM2[site], netCFlow, som1c_surface, ratioCNtoSOM2, site);
                    //PlugIn.ModelCore.UI.WriteLine(".  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                }
            }


            //---------------------------------------------------------------------
            // Soil SOM1 decomposes to SOM2 and SOM3 with CO2 loss and leaching

            double som1c_soil = SiteVars.SOM1soil[site].Carbon;

            //PlugIn.ModelCore.UI.WriteLine("SOM1soil[site].Carbon={0:0.00}", som1c_soil);
            //PlugIn.ModelCore.UI.WriteLine("SiteVars.MineralN = {0:0.00} - pre SOM1.", SiteVars.MineralN[site]);

            if (som1c_soil > 0.0000001)
            {
                //Determine C/N ratios for flows to som2
                double ratioCNtoSOM2 = Layer.BelowgroundDecompositionRatio(site,
                                                                           OtherData.MinCNenterSOM2,
                                                                           OtherData.MaxCNenterSOM2,
                                                                           OtherData.MinContentN_SOM2);

                //Compute total C flow out of soil microbes.
                //Added impact of soil anaerobic conditions -rm 12/91
                double textureEffect = OtherData.TextureEffectIntercept
                                       + OtherData.TextureEffectSlope * EcoregionData.PercentSand[ecoregion];

                double anerb = SiteVars.AnaerobicEffect[site];

                //PlugIn.ModelCore.UI.WriteLine("SiteVars.DecayFactor = {0:0.00}, SoilDecayRateMicrobes = {1:0.00}, texture = {2:0.00}, anerb = {3:0.00}, MonthAdjust = {4:0.00}.",
                double totalCflow = som1c_soil
                                    * SiteVars.DecayFactor[site]
                                    * OtherData.LitterParameters[(int)LayerType.Soil].DecayRateMicrobes
                                    * EcoregionData.DecayRateSOM1[ecoregion]
                                    * textureEffect
                                    * anerb
                                    * OtherData.MonthAdjust;

                // If soil SOM1 can decompose to SOM2, it will also go to SOM3.
                // If it can't go to SOM2, it can't decompose at all.
                // First determine if decomposition can occur:
                if (SiteVars.SOM1soil[site].DecomposePossible(ratioCNtoSOM2, SiteVars.MineralN[site]))
                {
                    //CO2 Loss - Compute and schedule respiration flows
                    double P1CO2_Soil = OtherData.P1CO2_Soil_Intercept + OtherData.P1CO2_Soil_Slope * EcoregionData.PercentSand[ecoregion];

                    double co2loss  = totalCflow * P1CO2_Soil;
                    double netCFlow = totalCflow - co2loss;
                    SiteVars.SOM1soil[site].Respiration(co2loss, site);

                    // Decompose Soil SOM1 to SOM3
                    // The fraction of totalCflow that goes to SOM3 is a function of clay content.
                    double clayEffect = OtherData.PS1S3_Intercept + (OtherData.PS1S3_Slope * EcoregionData.PercentClay[ecoregion]);
                    double cFlowS1S3  = netCFlow * clayEffect * (1.0 + OtherData.AnaerobicImpactSlope * (1.0 - anerb));

                    //Compute and schedule C & N flows and update mineralization accumulators
                    double ratioCNto3 = Layer.BelowgroundDecompositionRatio(site,
                                                                            OtherData.MinCNenterSOM3,
                                                                            OtherData.MaxCNenterSOM3,
                                                                            OtherData.MinContentN_SOM3);

                    //Partition and schedule C and N flows
                    SiteVars.SOM1soil[site].TransferCarbon(SiteVars.SOM3[site], cFlowS1S3);
                    SiteVars.SOM1soil[site].TransferNitrogen(SiteVars.SOM3[site], cFlowS1S3, som1c_soil, ratioCNto3, site);
                    //PlugIn.ModelCore.UI.WriteLine("AfterSOM1.  MineralN={0:0.00}.", SiteVars.MineralN[site]);

                    // Leaching of Organics
                    // This only occurs when the water flow out of water layer 2
                    // exceeds a critical value.  Use the same C/N ratios as for the flow to SOM3.

                    double cLeached = 0.0;                  // Carbon leached to a stream

                    if (SiteVars.WaterMovement[site] > 0.0) //Volume of water moving-ML.  Used to be an index of water movement that indicates saturation (amov)
                    {
                        //ML deleted the linten function which was poorly described in the Century manual.
                        //double leachTextureEffect = OtherData.OMLeachIntercept + OtherData.OMLeachSlope * EcoregionData.PercentSand[ecoregion];
                        //double linten = System.Math.Min(1.0 - ((OtherData.OMLeachWater - SiteVars.WaterMovement[site])  / OtherData.OMLeachWater), 1.0);
                        //cLeached = netCFlow * leachTextureEffect * linten;

                        double leachTextureEffect = OtherData.OMLeachIntercept + OtherData.OMLeachSlope * EcoregionData.PercentSand[ecoregion];

                        double indexWaterMovement = SiteVars.WaterMovement[site] / (EcoregionData.SoilDepth[ecoregion] * EcoregionData.FieldCapacity[ecoregion]);

                        cLeached = netCFlow * leachTextureEffect * indexWaterMovement;

                        //Partition and schedule C flows
                        SiteVars.SOM1soil[site].TransferCarbon(SiteVars.Stream[site], cLeached);

                        // Compute and schedule N flows and update mineralization accumulators
                        // Need to use the ratio for som1 for organic leaching
                        double ratioCN_SOM1soil = som1c_soil / SiteVars.SOM1soil[site].Nitrogen;
                        double orgflow          = cLeached / ratioCN_SOM1soil;

                        SiteVars.SOM1soil[site].Nitrogen -= orgflow;
                        SiteVars.Stream[site].Nitrogen   += orgflow;
                        //PlugIn.ModelCore.UI.WriteLine("DON Leaching. ratioCN_SOM1soil={0:0.00}, DON={1:0.00}.", ratioCN_SOM1soil, orgflow);

                        SiteVars.MonthlyStreamN[site][Main.Month] += orgflow;

                        //PlugIn.ModelCore.UI.WriteLine("DON Leaching. totalNLeach={0:0.0}, MineralN={1:0.00}", totalNleached, SiteVars.MineralN[site]);
                    }

                    // C & N movement from SOM1 to SOM2.
                    // SOM2 gets what's left of totalCflow.
                    double cFlowS1S2 = netCFlow - cFlowS1S3 - cLeached;

                    //Partition and schedule C and N flows
                    SiteVars.SOM1soil[site].TransferCarbon(SiteVars.SOM2[site], cFlowS1S2);
                    SiteVars.SOM1soil[site].TransferNitrogen(SiteVars.SOM2[site], cFlowS1S2, som1c_soil, ratioCNtoSOM2, site);
                    //PlugIn.ModelCore.UI.WriteLine("PartitionCN.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                }
            }


            //---------------------------------------------------------------------
            //**********SOM2 decomposes to soil SOM1 and SOM3 with CO2 loss**********

            double som2c = SiteVars.SOM2[site].Carbon;

            if (som2c > 0.0000001)
            {
                // Determine C/N ratios for flows to SOM1
                double ratioCNto1 = Layer.BelowgroundDecompositionRatio(site,
                                                                        OtherData.MinCNenterSOM1,
                                                                        OtherData.MaxCNenterSOM1,
                                                                        OtherData.MinContentN_SOM1);

                double anerb = SiteVars.AnaerobicEffect[site];

                // Compute total C flow out of SOM2C
                double totalCflow = som2c
                                    * SiteVars.DecayFactor[site]
                                    * EcoregionData.DecayRateSOM2[ecoregion]
                                    * anerb //impact of soil anaerobic conditions
                                    * OtherData.MonthAdjust;
                //PlugIn.ModelCore.UI.WriteLine("som2c={0:0.00}, decayFactor={1:0.00}, decayRateSOM2={2:0.00}, anerb={3:0.00}, monthAdj={4:0.00}", som2c, SiteVars.DecayFactor[site], EcoregionData.DecayRateSOM2[ecoregion], anerb, OtherData.MonthAdjust);

                // If SOM2 can decompose to SOM1, it will also go to SOM3.
                // If it can't go to SOM1, it can't decompose at all.

                if (SiteVars.SOM2[site].DecomposePossible(ratioCNto1, SiteVars.MineralN[site]))
                //PlugIn.ModelCore.UI.WriteLine("DecomposePoss.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                {
                    //CO2 loss - Compute and schedule respiration flows
                    double co2loss  = totalCflow * OtherData.FractionSOM2toCO2;
                    double netCFlow = totalCflow - co2loss;
                    SiteVars.SOM2[site].Respiration(co2loss, site);
                    //PlugIn.ModelCore.UI.WriteLine("AfterTransferto.  MineralN={0:0.00}.", SiteVars.MineralN[site]);

                    // -----------------------------------------------
                    // Decompose SOM2 to SOM3, SOM3 gets what's left of totalCflow.
                    double clayEffect = OtherData.PS2S3_Intercept + OtherData.PS2S3_Slope * EcoregionData.PercentClay[ecoregion];
                    double cFlowS2S3  = netCFlow * clayEffect * (1.0 + OtherData.AnaerobicImpactSlope * (1.0 - anerb));

                    //Compute and schedule C and N flows and update mineralization accumulators
                    double ratioCNto3 = Layer.BelowgroundDecompositionRatio(site,
                                                                            OtherData.MinCNenterSOM3,
                                                                            OtherData.MaxCNenterSOM3,
                                                                            OtherData.MinContentN_SOM3);
                    //PlugIn.ModelCore.UI.WriteLine("TransferSOM2.  MineralN={0:0.00}.", SiteVars.MineralN[site]);

                    //Partition and schedule C and N flows
                    SiteVars.SOM2[site].TransferCarbon(SiteVars.SOM3[site], cFlowS2S3);
                    SiteVars.SOM2[site].TransferNitrogen(SiteVars.SOM3[site], cFlowS2S3, som2c, ratioCNto3, site);

                    // -----------------------------------------------
                    // Decompose SOM2 to SOM1
                    double cFlowS2S1 = netCFlow - cFlowS2S3;

                    // Compute and schedule N and C flows and update mineralization accumulators
                    ratioCNto1 = Layer.BelowgroundDecompositionRatio(site,
                                                                     OtherData.MinCNenterSOM1,
                                                                     OtherData.MaxCNenterSOM1,
                                                                     OtherData.MinContentN_SOM1);

                    //Partition and schedule C and N flows
                    SiteVars.SOM2[site].TransferCarbon(SiteVars.SOM1soil[site], cFlowS2S1);
                    SiteVars.SOM2[site].TransferNitrogen(SiteVars.SOM1soil[site], cFlowS2S1, som2c, ratioCNto1, site);
                    //PlugIn.ModelCore.UI.WriteLine("AfterSOM2.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                }
            }

            //---------------------------------------------------------------------
            // SOM3 decomposes to soil SOM1 with CO2 loss

            double som3c = SiteVars.SOM3[site].Carbon;

            if (som3c > 0.0000001)
            {
                //Determine C/N ratios for flows to SOM1.
                double ratioCNto1 = Layer.BelowgroundDecompositionRatio(site,
                                                                        OtherData.MinCNenterSOM1,
                                                                        OtherData.MaxCNenterSOM1,
                                                                        OtherData.MinContentN_SOM1);

                double anerb = SiteVars.AnaerobicEffect[site];

                //Compute total C flow out of SOM3C
                double totalCflow = som3c
                                    * SiteVars.DecayFactor[site]
                                    * EcoregionData.DecayRateSOM3[ecoregion]
                                    * anerb
                                    * OtherData.MonthAdjust;


                //If decomposition can occur,
                if (SiteVars.SOM3[site].DecomposePossible(ratioCNto1, SiteVars.MineralN[site]))
                {
                    // CO2 loss - Compute and schedule respiration flows.
                    double co2loss  = totalCflow * OtherData.FractionSOM3toCO2 * anerb;
                    double netCFlow = totalCflow - co2loss;
                    SiteVars.SOM3[site].Respiration(co2loss, site);

                    // Decompose SOM3 to soil SOM1
                    double cFlowS3S1 = netCFlow;

                    // Partition and schedule C and N flows
                    SiteVars.SOM3[site].TransferCarbon(SiteVars.SOM1soil[site], cFlowS3S1);
                    SiteVars.SOM3[site].TransferNitrogen(SiteVars.SOM1soil[site], cFlowS3S1, som3c, ratioCNto1, site);
                    //PlugIn.ModelCore.UI.WriteLine("AfterSOM3.  MineralN={0:0.00}.", SiteVars.MineralN[site]);
                }
            }
        }