public void LocalComputeMethod()
 {
     CohortDefoliation.Delegates.Compute computeMethod = CohortDefoliation.Compute;
     try {
         CohortDefoliation.Compute = MyCompute;
         myComputeCalled           = false;
         Assert.AreEqual(myComputeResult, CohortDefoliation.Compute(myCohort,
                                                                    myActiveSite,
                                                                    mySiteBiomass));
         Assert.IsTrue(myComputeCalled);
     }
     finally {
         // Restore the compute delegate.
         CohortDefoliation.Compute = computeMethod;
     }
 }
예제 #2
0
        //---------------------------------------------------------------------

        /// <summary>
        /// Computes the change in a cohort's biomass due to Annual Net Primary
        /// Productivity (ANPP), age-related mortality (M_AGE), and development-
        /// related mortality (M_BIO).
        /// </summary>
        public int ComputeChange(ICohort cohort,
                                 ActiveSite site)
        {
            ecoregion = PlugIn.ModelCore.Ecoregion[site];
            int siteBiomass = SiteVars.TotalBiomass[site];

            //Save the pre-growth root biomass. This needs to be calculated BEFORE growth and mortality
            double TotalRoots = Roots.CalculateRootBiomass(site, cohort.Species, cohort.Biomass);

            SiteVars.soilClass[site].CollectRootBiomass(TotalRoots, 0);

            // First, calculate age-related mortality.
            // Age-related mortality will include woody and standing leaf biomass (=0 for deciduous trees).
            double mortalityAge = ComputeAgeMortality(cohort);

            double actualANPP = ComputeActualANPP(cohort, site, siteBiomass, SiteVars.PreviousYearMortality[site]);

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

            //  Growth-related mortality
            double mortalityGrowth = ComputeGrowthMortality(cohort, site, siteBiomass);

            //  Age-related mortality is discounted from growth-related
            //  mortality to prevent the under-estimation of mortality.  Cannot be negative.
            mortalityGrowth = Math.Max(0, mortalityGrowth - mortalityAge);

            //  Also ensure that growth mortality does not exceed actualANPP.
            mortalityGrowth = Math.Min(mortalityGrowth, actualANPP);

            //  Total mortality for the cohort
            double totalMortality = mortalityAge + mortalityGrowth;

            if (totalMortality > cohort.Biomass)
            {
                throw new ApplicationException("Error: Mortality exceeds cohort biomass");
            }

            // Defoliation ranges from 1.0 (total) to none (0.0).
            defoliation = CohortDefoliation.Compute(cohort, site, siteBiomass);
            double defoliationLoss = 0.0;

            if (defoliation > 0)
            {
                double standing_nonwood = ComputeFractionANPPleaf(cohort.Species) * actualANPP;
                defoliationLoss = standing_nonwood * defoliation;
                SiteVars.soilClass[site].DisturbanceImpactsDOM(site, "defol", 0);  //just soil impacts. Dist impacts are handled differently??
            }

            int    deltaBiomass = (int)(actualANPP - totalMortality - defoliationLoss);
            double newBiomass   = cohort.Biomass + (double)deltaBiomass;

            double totalLitter = UpdateDeadBiomass(cohort, actualANPP, totalMortality, site, newBiomass);

            //if (site.Location.Row == 279 && site.Location.Column == 64 && cohort.Species.Name == "Pl")
            //{
            //    PlugIn.ModelCore.UI.WriteLine("Yr={0},  Age={1}, mortGrow={2}, mortAge={3}, ANPP={4}, totLitter={5}", PlugIn.ModelCore.CurrentTime, cohort.Age, mortalityGrowth, mortalityAge, actualANPP, totalLitter);
            // }

            //if (cohort.Species.Name == "pinubank")
            //{
            //PlugIn.ModelCore.UI.WriteLine("Age={0}, ANPPact={1:0.0}, M={2:0.0}, litter={3:0.00}.", cohort.Age, actualANPP, totalMortality, totalLitter);
            //PlugIn.ModelCore.UI.WriteLine("Name={0}, Age={1}, B={2}, ANPPact={3:0.0}, delta={4:0.0}", cohort.Species.Name, cohort.Age, cohort.Biomass, actualANPP, deltaBiomass);
            //    PlugIn.ModelCore.UI.WriteLine("Name={0}, Age={1}, B={2}, Mage={3:0.0}, Mgrowth={4:0.0}, ANPPact={5:0.0}, delta={6:0.0}, newbiomass={7:0.0}", cohort.Species.Name, cohort.Age, cohort.Biomass, mortalityAge, mortalityGrowth, actualANPP, deltaBiomass, newBiomass);
            //}
            //The KillNow flag indicates that this is the year of growth in which to kill off some cohorts in order to make snags.
            if (SiteVars.soilClass[site].bKillNow && Snags.bSnagsPresent)
            {
                //if (SiteVars.soilClass[site].diedAt == cohort.Age && SiteVars.soilClass[site].spIndex == cohort.Species.Index)
                //there could be more than one species-age combination, so we have to loop through them.
                //However, the user has been asked to put the ages in order from smallest to largest, so we can stop looking
                //as soon as we reach an age that is older than the cohort's age.
                for (int idx = 0; idx < Snags.NUMSNAGS; idx++)
                {
                    if (cohort.Age == Snags.DiedAt[idx] && Snags.initSpecIdx[idx] == cohort.Species.Index)
                    {
                        deltaBiomass = -cohort.Biomass; //set biomass to 0 to make core remove this from the list

                        //when this cohort gets passed to the cohort died event, there is no longer any biomass present, so
                        //we have to capture the biomass information here, while we still can.

                        double foliar = (double)cohort.ComputeNonWoodyBiomass(site);
                        double wood   = ((double)cohort.Biomass - foliar);
                        Snags.bSnagsUsed[idx] = true;

                        SiteVars.soilClass[site].CollectBiomassMortality(cohort.Species, cohort.Age, wood, foliar, 5 + idx);
                    }
                    if (Snags.DiedAt[idx] > cohort.Age || Snags.DiedAt[idx] == 0)
                    {
                        break;
                    }
                }
            }
            if (deltaBiomass > -cohort.Biomass)
            {   //if we didn't kill this cohort to make a snag, then update the post-growth root biomass.
                TotalRoots = Roots.CalculateRootBiomass(site, cohort.Species, newBiomass);
                SiteVars.soilClass[site].CollectRootBiomass(TotalRoots, 1);
            }


            return(deltaBiomass);
        }
 public void DefaultIs0()
 {
     Assert.AreEqual(0.0, CohortDefoliation.Compute(null, null, 0));
 }