//---------------------------------------------------------------------

        int IDisturbance.ReduceOrKillMarkedCohort(ICohort cohort)
        {
            int reduction;
            if (reductions[cohort.Species.Index].TryGetValue(cohort.Age, out reduction))
            {

                int litter = cohort.ComputeNonWoodyBiomass(currentSite);
                int woody = reduction - litter;

                SiteVars.BiomassRemoved[currentSite] += reduction;
                SiteVars.WoodyDebris[currentSite].Mass += woody;
                SiteVars.Litter[currentSite].Mass += litter;

                SiteVars.CohortsPartiallyDamaged[currentSite]++;

                if (originalStand.LastPrescription.PreventEstablishment)
                {
                    numberCohortsReduced++;
                    capacityReduction += (double) reduction / (double) cohort.Biomass;
                }

                // Record any cohort touched, not just killed:
                BaseHarvest.SiteVars.Stand[currentSite].UpdateDamageTable(cohort.Species.Name);

                BaseHarvest.SiteVars.Stand[currentSite].RecordBiomassRemoved(cohort.Species, reduction);

                return reduction;
            }
            else
                return 0;
        }
Ejemplo n.º 2
0
        public static void CohortDied(object sender,
                                      DeathEventArgs eventArgs)
        {
            ExtensionType   disturbanceType  = eventArgs.DisturbanceType;
            PoolPercentages cohortReductions = Module.Parameters.CohortReductions[disturbanceType];

            ICohort    cohort   = (Landis.Library.BiomassCohorts.ICohort)eventArgs.Cohort;
            ActiveSite site     = eventArgs.Site;
            int        nonWoody = cohort.ComputeNonWoodyBiomass(site);
            int        woody    = (cohort.Biomass - nonWoody);

            int nonWoodyInput = ReduceInput(nonWoody, cohortReductions.Foliar);
            int woodyInput    = ReduceInput(woody, cohortReductions.Wood);

            //ForestFloor.AddBiomass(woodyInput, nonWoodyInput, cohort.Species, site);
            ForestFloor.AddWoody(woodyInput, cohort.Species, site);
            ForestFloor.AddLitter(nonWoodyInput, cohort.Species, site);
        }
        public static void CohortDied(object sender,
                                      DeathEventArgs eventArgs)
        {
            ExtensionType disturbanceType = eventArgs.DisturbanceType;
            //PoolPercentages cohortReductions = Module.Parameters.CohortReductions[disturbanceType];

            ICohort    cohort = eventArgs.Cohort;
            ActiveSite site   = eventArgs.Site;

            if (disturbanceType.IsMemberOf("disturbance:harvest"))      //base harvest doesn't get here ever, but biomass harvest does.
            {
                return;                                                 //It has already been accounted for, however in PlugIn.CohortDied, so don't repeat here.
            }
            double foliar = (double)cohort.ComputeNonWoodyBiomass(site);
            double wood   = ((double)cohort.Biomass - foliar);

            SiteVars.soilClass[site].DisturbanceImpactsBiomass(site, cohort.Species, cohort.Age, wood, foliar, disturbanceType.Name, 0);
        }
Ejemplo n.º 4
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 CohortTotalMortality(object sender, DeathEventArgs eventArgs)
        {
            ExtensionType disturbanceType = eventArgs.DisturbanceType;
            ActiveSite    site            = eventArgs.Site;

            ICohort cohort      = (Landis.Library.BiomassCohorts.ICohort)eventArgs.Cohort;
            int     foliarInput = cohort.ComputeNonWoodyBiomass(site);
            int     woodInput   = (cohort.Biomass - foliarInput);

            if (disturbanceType != null)
            {
                if (PlugIn.CalibrateMode && PlugIn.ModelCore.CurrentTime > 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("   BIOMASS SUCCESSION TOTAL MORTALITY: species={0}, age={1}, woodInput={2}, foliarInputs={3}.", cohort.Species.Name, cohort.Age, woodInput, foliarInput);
                }

                if (disturbanceType.IsMemberOf("disturbance:fire"))
                {
                    SiteVars.FireSeverity = PlugIn.ModelCore.GetSiteVar <byte>("Fire.Severity");
                    Landis.Library.Succession.Reproduction.CheckForPostFireRegen(eventArgs.Cohort, site);

                    if (!Disturbed[site])  // the first cohort killed/damaged
                    {
                        if (SiteVars.FireSeverity != null && SiteVars.FireSeverity[site] > 0)
                        {
                            FireEffects.ReduceLayers(SiteVars.FireSeverity[site], site);
                        }
                    }

                    double woodFireConsumption   = woodInput * (float)FireEffects.ReductionsTable[(int)SiteVars.FireSeverity[site]].CoarseLitterReduction;
                    double foliarFireConsumption = foliarInput * (float)FireEffects.ReductionsTable[(int)SiteVars.FireSeverity[site]].FineLitterReduction;

                    woodInput   -= (int)woodFireConsumption;
                    foliarInput -= (int)foliarFireConsumption;
                }
                else
                {
                    if (disturbanceType.IsMemberOf("disturbance:harvest"))
                    {
                        SiteVars.HarvestPrescriptionName = PlugIn.ModelCore.GetSiteVar <string>("Harvest.PrescriptionName");
                        if (!Disturbed[site])  // the first cohort killed/damaged
                        {
                            HarvestEffects.ReduceLayers(SiteVars.HarvestPrescriptionName[site], site);
                        }
                        woodInput   -= (int)(woodInput * (float)HarvestEffects.GetCohortWoodRemoval(site));
                        foliarInput -= (int)(foliarInput * (float)HarvestEffects.GetCohortLeafRemoval(site));
                    }

                    // If not fire, check for resprouting:
                    Landis.Library.Succession.Reproduction.CheckForResprouting(eventArgs.Cohort, site);
                }
            }

            //PlugIn.ModelCore.UI.WriteLine("Cohort Died: species={0}, age={1}, wood={2:0.00}, foliage={3:0.00}.", cohort.Species.Name, cohort.Age, wood, foliar);
            ForestFloor.AddWoody(woodInput, cohort.Species, eventArgs.Site);
            ForestFloor.AddLitter(foliarInput, cohort.Species, eventArgs.Site);

            // Assume that ALL dead root biomass stays on site.
            //Roots.AddCoarseRootLitter(Roots.CalculateCoarseRoot(cohort, cohort.WoodBiomass), cohort, cohort.Species, eventArgs.Site);
            //Roots.AddFineRootLitter(Roots.CalculateFineRoot(cohort, cohort.LeafBiomass), cohort, cohort.Species, eventArgs.Site);

            if (disturbanceType != null)
            {
                Disturbed[site] = true;
            }

            return;

            //ExtensionType disturbanceType = eventArgs.DisturbanceType;
            //if (disturbanceType != null)
            //{
            //    ActiveSite site = eventArgs.Site;
            //    Disturbed[site] = true;
            //    if (disturbanceType.IsMemberOf("disturbance:fire"))
            //        Reproduction.CheckForPostFireRegen(eventArgs.Cohort, site);
            //    else
            //        Reproduction.CheckForResprouting(eventArgs.Cohort, site);
            //}
        }