Esempio n. 1
0
        //---------------------------------------------------------------------

        private double ComputeActualANPP(ICohort cohort,
                                         ActiveSite site,
                                         int siteBiomass,
                                         int prevYearSiteMortality)
        {
            growthReduction = CohortGrowthReduction.Compute(cohort, site);

            double cohortBiomass     = cohort.Biomass;
            double capacityReduction = 1.0;
            double maxANPP           = SpeciesData.ANPP_MAX_Spp[cohort.Species][ecoregion];
            //double maxBiomass = SpeciesData.B_MAX_Spp[cohort.Species][ecoregion];  //CForCS
            double maxBiomass  = SpeciesData.B_MAX_Spp[cohort.Species][ecoregion] * capacityReduction;
            double growthShape = SpeciesData.GrowthCurveShapeParm[cohort.Species];

            if (SiteVars.CapacityReduction != null && SiteVars.CapacityReduction[site] > 0)
            {
                capacityReduction = 1.0 - SiteVars.CapacityReduction[site];
                if (PlugIn.CalibrateMode)
                {
                    PlugIn.ModelCore.UI.WriteLine("Yr={0}. Capacity Remaining={1:0.00}, Spp={2}, Age={3} B={4}.", (PlugIn.ModelCore.CurrentTime + SubYear), capacityReduction, cohort.Species.Name, cohort.Age, cohort.Biomass);
                }
            }

            double indexC = CalculateCompetition(site, cohort);   //Biomass model

            //if ((indexC <= 0.0 && cohortBiomass > 0) || indexC > 1.0)   //Biomass model
            //    throw new ApplicationException("Application terminating.");

            //  Potential biomass, equation 3 in Scheller and Mladenoff, 2004
            //double potentialBiomass = Math.Max(1, maxBiomass - siteBiomass);  //old CForCS
            double potentialBiomass = Math.Max(1, maxBiomass - siteBiomass + cohortBiomass);  //Biomass model

            //  Species can use new space immediately
            //  but not in the case of capacity reduction due to harvesting.
            if (capacityReduction >= 1.0)
            {
                potentialBiomass = Math.Max(potentialBiomass, prevYearSiteMortality);
            }

            //  Ratio of cohort's actual biomass to potential biomass
            B_AP = Math.Min(1.0, cohortBiomass / potentialBiomass);

            //  Ratio of cohort's potential biomass to maximum biomass.  The
            //  ratio cannot be exceed 1.
            //B_PM = Math.Min(1.0, potentialBiomass / maxBiomass);     //old CForCS
            B_PM = Math.Min(1.0, indexC);   //Biomass model

            //  Actual ANPP: equation (4) from Scheller & Mladenoff, 2004.
            //  Constants k1 and k2 control whether growth rate declines with
            //  age.  Set to default = 1.
            //double actualANPP = maxANPP * Math.E * B_AP * Math.Exp(-1 * B_AP) * B_PM;   //old CForCS
            double actualANPP = maxANPP * Math.E * Math.Pow(B_AP, growthShape) * Math.Exp(-1 * Math.Pow(B_AP, growthShape)) * B_PM;   //Biomass model

            // Calculated actual ANPP can not exceed the limit set by the
            //  maximum ANPP times the ratio of potential to maximum biomass.
            //  This down regulates actual ANPP by the available growing space.

            actualANPP = Math.Min(maxANPP * B_PM, actualANPP);

            if (growthReduction > 0)
            {
                actualANPP *= (1.0 - growthReduction);
            }

            //if (site.Location.Row == 279 && site.Location.Column == 64 && cohort.Species.Name == "Pl")
            //{
            //    PlugIn.ModelCore.UI.WriteLine("Yr={0},  Age={1}, PotBio={2}, CohortBio={3}, maxBio={4}, siteBio={5}, ANPP={6}.", PlugIn.ModelCore.CurrentTime, cohort.Age, potentialBiomass, cohort.Biomass, maxBiomass, siteBiomass, actualANPP);
            //}

            return(actualANPP);
        }
        //---------------------------------------------------------------------

        private double[] ComputeActualANPP(ICohort cohort,
                                           ActiveSite site,
                                           double siteBiomass,
                                           double[]   mortalityAge)
        {
            double leafFractionNPP = FunctionalType.Table[SpeciesData.FuncType[cohort.Species]].FCFRACleaf;
            double maxBiomass      = SpeciesData.Max_Biomass[cohort.Species]; //.B_MAX_Spp[cohort.Species][ecoregion];
            double sitelai         = SiteVars.LAI[site];
            double maxNPP          = SpeciesData.Max_ANPP[cohort.Species];    //.ANPP_MAX_Spp[cohort.Species][ecoregion];

            double limitT = calculateTemp_Limit(site, cohort.Species);

            double limitH20 = calculateWater_Limit(site, ecoregion, cohort.Species);

            double limitLAI = calculateLAI_Limit(cohort, site);

            // RMS 03/2016: Testing alternative more similar to how Biomass Succession operates: REMOVE FOR NEXT RELEASE
            //double limitCapacity = 1.0 - Math.Min(1.0, Math.Exp(siteBiomass / maxBiomass * 5.0) / Math.Exp(5.0));

            double competition_limit = calculateCompetition_Limit(cohort, site);

            //double potentialNPP_NoN = maxNPP * limitLAI * limitH20 * limitT; // * limitCapacity;
            double potentialNPP = maxNPP * limitLAI * limitH20 * limitT * competition_limit;
            //double potentialNPP = maxNPP * limitLAI * limitH20 * limitT * limitCapacity;

            double limitN = calculateN_Limit(site, cohort, potentialNPP, leafFractionNPP);

            potentialNPP *= limitN;

            //if (Double.IsNaN(limitT) || Double.IsNaN(limitH20) || Double.IsNaN(limitLAI) || Double.IsNaN(limitCapacity) || Double.IsNaN(limitN))
            //{
            //    PlugIn.ModelCore.UI.WriteLine("  A limit = NaN!  Will set to zero.");
            //    PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}.     GROWTH LIMITS: LAI={2:0.00}, H20={3:0.00}, N={4:0.00}, T={5:0.00}, Capacity={6:0.0}", PlugIn.ModelCore.CurrentTime, month + 1, limitLAI, limitH20, limitN, limitT, limitCapacity);
            //    PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}.     Other Information: MaxB={2}, Bsite={3}, Bcohort={4:0.0}, SoilT={5:0.0}.", PlugIn.ModelCore.CurrentTime, month + 1, maxBiomass, (int)siteBiomass, (cohort.WoodBiomass + cohort.LeafBiomass), SiteVars.SoilTemperature[site]);
            //}


            //  Age mortality is discounted from ANPP to prevent the over-
            //  estimation of growth.  ANPP cannot be negative.
            double actualANPP = Math.Max(0.0, potentialNPP - mortalityAge[0] - mortalityAge[1]);

            // Growth can be reduced by another extension via this method.
            // To date, no extension has been written to utilize this hook.
            double growthReduction = CohortGrowthReduction.Compute(cohort, site);

            if (growthReduction > 0.0)
            {
                actualANPP *= (1.0 - growthReduction);
            }

            double leafNPP = actualANPP * leafFractionNPP;
            double woodNPP = actualANPP * (1.0 - leafFractionNPP);

            if (Double.IsNaN(leafNPP) || Double.IsNaN(woodNPP))
            {
                PlugIn.ModelCore.UI.WriteLine("  EITHER WOOD or LEAF NPP = NaN!  Will set to zero.");
                //PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}, SpeciesName={2}, CohortAge={3}.   GROWTH LIMITS: LAI={4:0.00}, H20={5:0.00}, N={6:0.00}, T={7:0.00}, Capacity={8:0.0}.", PlugIn.ModelCore.CurrentTime, Main.Month + 1, cohort.Species.Name, cohort.Age, limitLAI, limitH20, limitN, limitT, limitCapacity);
                PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}.     Other Information: MaxB={2}, Bsite={3}, Bcohort={4:0.0}, SoilT={5:0.0}.", PlugIn.ModelCore.CurrentTime, Main.Month + 1, maxBiomass, (int)siteBiomass, (cohort.WoodBiomass + cohort.LeafBiomass), SiteVars.SoilTemperature[site]);
                PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}.     WoodNPP={2:0.00}, LeafNPP={3:0.00}.", PlugIn.ModelCore.CurrentTime, Main.Month + 1, woodNPP, leafNPP);
                if (Double.IsNaN(leafNPP))
                {
                    leafNPP = 0.0;
                }
                if (Double.IsNaN(woodNPP))
                {
                    woodNPP = 0.0;
                }
            }

            if (PlugIn.ModelCore.CurrentTime > 0 && OtherData.CalibrateMode)
            {
                //Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},{2:0.00},{3:0.00}, {4:0.00},", limitLAI, limitH20, limitT, limitCapacity, limitN);
                Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},{2:0.00},{3:0.00},", limitLAI, limitH20, limitT, limitN);
                Outputs.CalibrateLog.Write("{0},{1},{2},{3:0.0},{4:0.0},", maxNPP, maxBiomass, (int)siteBiomass, (cohort.WoodBiomass + cohort.LeafBiomass), SiteVars.SoilTemperature[site]);
                Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},", woodNPP, leafNPP);
            }

            return(new double[2] {
                woodNPP, leafNPP
            });
        }
Esempio n. 3
0
        //---------------------------------------------------------------------

        private double ComputeActualANPP(ICohort cohort, ActiveSite site)
        {
            int siteBiomass = SiteVars.TotalBiomass[site];

            // ---------------------------------------------------------
            // Growth reduction ranges from 1.0 (total) to none (0.0).
            // Growth reduction is calculated by an disturbance function, typically an extension
            // with a dedicated calculator.  The method CohortGrowthReduction.Compute is a delegate method
            // and lives within the disturbance extension.

            growthReduction = CohortGrowthReduction.Compute(cohort, site);

            double growthShape       = SpeciesData.GrowthCurveShapeParm[cohort.Species];
            double cohortBiomass     = cohort.Biomass;
            double capacityReduction = 1.0;

            if (SiteVars.CapacityReduction != null && SiteVars.CapacityReduction[site] > 0)
            {
                capacityReduction = 1.0 - SiteVars.CapacityReduction[site];
                if (PlugIn.CalibrateMode)
                {
                    PlugIn.ModelCore.UI.WriteLine("Yr={0}. Capacity Remaining={1:0.00}, Spp={2}, Age={3} B={4}.", (PlugIn.ModelCore.CurrentTime + SubYear), capacityReduction, cohort.Species.Name, cohort.Age, cohort.Biomass);
                }
            }

            double maxBiomass = SpeciesData.B_MAX_Spp[cohort.Species, ecoregion] * capacityReduction;
            double maxANPP    = SpeciesData.ANPP_MAX_Spp[cohort.Species, ecoregion];

            //  Potential biomass, equation 3 in Scheller and Mladenoff, 2004
            double potentialBiomass = Math.Max(1.0, maxBiomass - siteBiomass + cohortBiomass);

            //  Species can use new space from mortality immediately
            //  but not in the case of capacity reduction due to harvesting.
            if (capacityReduction >= 1.0)
            {
                potentialBiomass = Math.Max(potentialBiomass, SiteVars.PreviousYearMortality[site]);
            }

            //  Ratio of cohort's actual biomass to potential biomass
            B_AP = cohortBiomass / potentialBiomass;

            double indexC = CalculateCompetition(site, cohort);

            if ((indexC <= 0.0 && cohortBiomass > 0) || indexC > 1.0)
            {
                PlugIn.ModelCore.UI.WriteLine("Error: Competition Index [{0:0.00}] is <= 0.0 or > 1.0", indexC);
                PlugIn.ModelCore.UI.WriteLine("Yr={0}. SPECIES={1}, AGE={2}, B={3}", (PlugIn.ModelCore.CurrentTime + SubYear), cohort.Species.Name, cohort.Age, cohortBiomass);

                throw new ApplicationException("Application terminating.");
            }

            B_PM = indexC;
            // PlugIn.ModelCore.Log.WriteLine("indexC={0:0.00}, lightIndexC={1:0.00}, OldSchool={2:0.00}.", indexC, indexLightC, indexOldSchool);

            //  Actual ANPP: equation (4) from Scheller & Mladenoff, 2004.
            double actualANPP = maxANPP * Math.E * Math.Pow(B_AP, growthShape) * Math.Exp(-1 * Math.Pow(B_AP, growthShape)) * B_PM;

            // Calculated actual ANPP can not exceed the limit set by the
            //  maximum ANPP times the ratio of potential to maximum biomass.
            //  This down regulates actual ANPP by the available growing space.

            actualANPP = Math.Min(maxANPP * B_PM, actualANPP);

            if (growthReduction > 0)
            {
                actualANPP *= (1.0 - growthReduction);
            }

            if (PlugIn.CalibrateMode && PlugIn.ModelCore.CurrentTime > 0)
            {
                PlugIn.ModelCore.UI.WriteLine("Yr={0}. Calculate ANPPactual...", (PlugIn.ModelCore.CurrentTime + SubYear));
                PlugIn.ModelCore.UI.WriteLine("Yr={0}.     Spp={1}, Age={2}.", (PlugIn.ModelCore.CurrentTime + SubYear), cohort.Species.Name, cohort.Age);
                PlugIn.ModelCore.UI.WriteLine("Yr={0}.     MaxANPP={1}, MaxB={2:0}, Bsite={3}, Bcohort={4:0.0}.", (PlugIn.ModelCore.CurrentTime + SubYear), maxANPP, maxBiomass, (int)siteBiomass, cohort.Biomass);
                PlugIn.ModelCore.UI.WriteLine("Yr={0}.     B_PM={1:0.0}, B_AP={2:0.0}, actualANPP={3:0.0}, capacityReduction={4:0.0}.", (PlugIn.ModelCore.CurrentTime + SubYear), B_PM, B_AP, actualANPP, capacityReduction);
            }

            return(actualANPP);
        }