//--------------------------------------------------------------------- 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; }
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); }
//--------------------------------------------------------------------- /// <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); //} }