//--------------------------------------------------------------------- /// <summary> /// Adds frass for a species to the foliar LITTER pools at a site. /// Assumes that some of the N has been resorbed. /// </summary> public static void AddFrassLitter(double inputFrassBiomass, ISpecies species, ActiveSite site) { double inputDecayValue = 1.0; // Decay value is calculated for surface/soil layers (leaf/fine root), // therefore, this is just a dummy value. if (inputFrassBiomass > 0) { //SiteVars.LitterfallC[site] += defoliatedLeafBiomass * 0.47; //double frassBiomass = Math.Max(0.0, OtherData.frassdepk * defoliatedLeafBiomass); // Frass C added is a function of defoliated leaf biomass, but adjusted for the CN of litter and frass // Any C lost is due to insect metabolism double inputFrassC = inputFrassBiomass * 0.47; double inputFrassN = inputFrassC / (double) SpeciesData.LeafLitterCN[species]; double actualFrassC = inputFrassN * (double) OtherData.CNratiofrass; // the difference between input and actual is C lost to insect metabolism double actualFrassBiomass = actualFrassC / 0.47; //PlugIn.ModelCore.UI.WriteLine("AddFrass.Month={0:0}, inputfrassN={1:0.000}, inputfrassbiomass={2:0.00}, actualfrassbiomass={3:0.00} ", Century.Month, inputFrassN, inputFrassBiomass, actualFrassBiomass); SiteVars.FrassC[site] += actualFrassC; LitterLayer.PartitionResidue( actualFrassBiomass, inputDecayValue, OtherData.CNratiofrass, 0.1, OtherData.StructuralCN, LayerName.Leaf, LayerType.Surface, site); } }
public void WriteHeader(ActiveSite site) { StreamWriter sw = new StreamWriter(OutputSiteFileName(site)); string s = "Year" + delim + "Month" + delim + "date" + delim + "NrOfCohorts" + delim + "Tday(C)" + delim + "Precip(mm_mo)" + delim + "RunOff(mm_mo)" + delim + "Transpiration(mm_mo)" + delim + "PrecipLoss(mm_mo)" + delim + "water(mm)" + delim + "SnowPack (mm)" + delim + "LAI(m2)" + delim + "VPD(kPa)" + delim + "GrossPsn(gC_mo)" + delim + "NetPsn(gC_mo)" + delim + "AutoResp(gC_mo)" + delim + "HeteroResp(gC_mo)" + delim + "TotalBiomass (gDW)" + delim + "TotalRoot (gDW)" + delim + "TotalFol (gDW)" + delim + "TotalNSC (gC)" + delim + "Litter(gDW_m2)" + delim + "CWD(gDW_m2)"; sw.WriteLine(s); sw.Close(); }
//--------------------------------------------------------------------- /// <summary> /// Computes the initial biomass for a cohort at a site. /// </summary> public static float[] InitialBiomass(ISpecies species, ISiteCohorts siteCohorts, ActiveSite site) { IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site]; double leafFrac = FunctionalType.Table[SpeciesData.FuncType[species]].FCFRACleaf; double B_ACT = SiteVars.ActualSiteBiomass(site); double B_MAX = SpeciesData.B_MAX_Spp[species][ecoregion]; // Initial biomass exponentially declines in response to // competition. double initialBiomass = 0.002 * B_MAX * Math.Exp(-1.6 * B_ACT / B_MAX); initialBiomass = Math.Max(initialBiomass, 5.0); double initialLeafB = initialBiomass * leafFrac; double initialWoodB = initialBiomass - initialLeafB; double[] initialB = new double[2]{initialWoodB, initialLeafB}; float[] initialWoodLeafBiomass = new float[2] { (float)initialB[0], (float)initialB[1] }; //PlugIn.ModelCore.UI.WriteLine("Yr={0},Mo={1}, InitialB={2:0.0}, InitBleaf={3:0.00}, InitBwood={4:0.00}. LeafFrac={5:0.0}", PlugIn.ModelCore.CurrentTime, month, initialBiomass, initialB[1], initialB[0], leafFrac); //PlugIn.ModelCore.UI.WriteLine("Yr={0},Mo={1}, B_MAX={2:0.0}, B_ACT={3:0.00}", PlugIn.ModelCore.CurrentTime, month, B_MAX, B_ACT); return initialWoodLeafBiomass; }
//--------------------------------------------------------------------- /// <summary> /// Grows all cohorts at a site for a specified number of years. The /// dead pools at the site also decompose for the given time period. /// </summary> public static void GrowCohorts(SiteCohorts cohorts, ActiveSite site, int years, bool isSuccessionTimestep) { if (cohorts == null) return; //CurrentYearSiteMortality = 0.0; for (int y = 1; y <= years; ++y) { SpeciesData.ChangeDynamicParameters(PlugIn.ModelCore.CurrentTime + y - 1); SiteVars.ResetAnnualValues(site); CohortBiomass.SubYear = y - 1; CohortBiomass.CanopyLightExtinction = 0.0; SiteVars.PercentShade[site] = 0.0; SiteVars.LightTrans[site] = 1.0; SiteVars.Cohorts[site].Grow(site, (y == years && isSuccessionTimestep)); SiteVars.WoodyDebris[site].Decompose(); SiteVars.Litter[site].Decompose(); } //SiteVars.PreviousYearMortality[site] = CurrentYearSiteMortality; }
/// <summary> /// Adds some biomass for a species to the WOODY pools at a site. /// </summary> public static void AddWoody(double woodyBiomass, ISpecies species, ActiveSite site) { SiteVars.WoodyDebris[site].AddMass(woodyBiomass, SpeciesData.WoodyDebrisDecay[species]); }
//--------------------------------------------------------------------- /// <summary> /// Computes the initial biomass for a cohort at a site. /// </summary> public static float[] InitialBiomass(ISpecies species, ISiteCohorts siteCohorts, ActiveSite site) { IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site]; double leafFrac = FunctionalType.Table[SpeciesData.FuncType[species]].FCFRACleaf; double branchFraction = FunctionalType.Table[SpeciesData.FuncType[species]].FCFRACbranch; //double Ndemand = 0.0; double B_ACT = SiteVars.ActualSiteBiomass(site); double B_MAX = SpeciesData.B_MAX_Spp[species][ecoregion]; // Initial biomass exponentially declines in response to // competition. double initialBiomass = 0.002 * B_MAX * Math.Exp(-1.6 * B_ACT / B_MAX); //Initial biomass is limited by nitrogen availability. //initialBiomass *= SpeciesData.NLimits[species]; initialBiomass = Math.Max(initialBiomass, 5.0); double initialLeafB = initialBiomass * leafFrac; double initialBranchB = initialBiomass* branchFraction; double initialWoodB = initialBiomass*(1 - leafFrac - branchFraction); double[] initialB = new double[3] { initialWoodB, initialBranchB, initialLeafB }; //PlugIn.ModelCore.Log.WriteLine("Yr={0},Mo={1}, InitialB={2:0.0}, InitBleaf={3:0.00}, InitBwood={4:0.00}. LeafFrac={5:0.0}", PlugIn.ModelCore.CurrentTime, month, initialBiomass, initialB[1], initialB[0], leafFrac); //PlugIn.ModelCore.Log.WriteLine("Yr={0},Mo={1}, B_MAX={2:0.0}, B_ACT={3:0.00}", PlugIn.ModelCore.CurrentTime, month, B_MAX, B_ACT); float[] initialWoodLeafBiomass = new float[3] { (float)initialB[0], (float)initialB[1], (float)initialB[2] }; //wang? return initialWoodLeafBiomass; }
//--------------------------------------------------------------------- /// <summary> /// Adds frass for a species to the foliar LITTER pools at a site. /// Assumes that some of the N has been resorbed. /// </summary> public static void AddFrassLitter(double defoliatedLeafBiomass, ISpecies species, ActiveSite site) { double inputDecayValue = 1.0; // Decay value is calculated for surface/soil layers (leaf/fine root), // therefore, this is just a dummy value. if (defoliatedLeafBiomass > 0) { SiteVars.LitterfallC[site] += defoliatedLeafBiomass * 0.47; double frassBiomass = Math.Max(0.0, OtherData.frassdepk * defoliatedLeafBiomass); double frassBiomassC = frassBiomass * 0.47; SiteVars.FrassC[site] += frassBiomassC; LitterLayer.PartitionResidue( frassBiomass, inputDecayValue, OtherData.CNratiofrass, 1.0, 1.0, //OtherData.CNratiofrass, LayerName.Leaf, LayerType.Surface, site); } }
public CohortBiomass(ActiveSite Site, ICohort Cohort, int Index) { this.cohort = Cohort; fRad = 0; site = Site; spc = Cohort.Species; }
public static void UpdateSiteData(DateTime date, ActiveSite site) { if (SiteOutput.HasSiteOutput[site] ==false) return; string s = date.Year.ToString() + delim + date.Month + delim + date.ToString("MM/yyyy") + delim + CanopyBiomass.NumberOfCanopyLayers[site] + delim + Static.Tday[date] + delim + Static.Prec[date] + delim + Hydrology.RunOff[site] + delim + Hydrology.WaterLeakage[site] + delim + Hydrology.Transpiration[site] + delim + Hydrology.Evaporation[site] + delim + Hydrology.Water[site] + delim + CanopyBiomass.CanopyLAI[site] + delim + Static.VPD[date] + delim + CanopyBiomass.GrossPsn[site] + delim + CanopyBiomass.NetPsn[site] + delim + CanopyBiomass.AutotrophicRespiration[site] + delim + ForestFloor.HeterotrophicRespiration[site] + delim + CanopyBiomass.TotalBiomass[site] + delim + CanopyBiomass.TotalRoot[site] + delim + CanopyBiomass.TotalFoliage[site] + delim + CanopyBiomass.TotalNSC[site] + delim + ForestFloor.Litter[site].Mass + delim + ForestFloor.WoodyDebris[site].Mass; FileContent.Add(s); }
public static void WriteHeader(ActiveSite site) { if (HasSiteOutput[site] == false) return; string FileName = OutputSiteFileName(site); StreamWriter sw = new StreamWriter(FileName); string s = "Year" + delim + "Month" + delim + "date" + delim + "CanopyLayers" + delim + "Tday(C)" + delim + "Precip(mm_mo)" + delim + "RunOff(mm_mo)" + delim + "WaterLeakage(mm_mo)" + delim + "Transpiration(mm)" + delim + "Evaporation(mm_mo)" + delim + "water(mm)" + delim + "LAI(m2)" + delim + "VPD(kPa)" + delim + "GrossPsn(gC_mo)" + delim + "NetPsn(gC_mo)" + delim + "AutoResp(gC_mo)" + delim + "HeteroResp(gC_mo)" + delim + "TotalBiomass (gDW)" + delim + "TotalRoot (gDW)" + delim + "TotalFol (gDW)" + delim + "TotalNSC (gC)" + delim + "Litter(gDW_m2)" + delim + "CWD(gDW_m2)"; sw.WriteLine(s); sw.Close(); }
//--------------------------------------------------------------------- /// <summary> /// Cuts the cohorts at a site. /// </summary> public override void Cut(ActiveSite site, CohortCounts cohortCounts) { if (isDebugEnabled) { log.DebugFormat(" {0} is cutting site {1}; cohorts are:", GetType().Name, site.Location); Debug.WriteSiteCohorts(log, site); } // Use age-only cohort selectors to harvest whole cohorts // Note: the base method sets the CurrentSite property, and resets // the counts to 0 before cutting. base.Cut(site, cohortCounts); // Then do any partial harvesting with the partial cohort selectors. this.cohortCounts = cohortCounts; SiteVars.Cohorts[site].ReduceOrKillBiomassCohorts(this); if (isDebugEnabled) { log.DebugFormat(" Cohorts after cutting site {0}:", site.Location); Debug.WriteSiteCohorts(log, site); } }
//--------------------------------------------------------------------- /// <summary> /// Adds some biomass for a species to the foliar LITTER pools at a site. /// </summary> public static void AddFoliageLitter(double foliarBiomass, ISpecies species, ActiveSite site) { double inputDecayValue = 1.0; // Decay value is calculated for surface/soil layers (leaf/fine root), // therefore, this is just a dummy value. if(foliarBiomass > 0) { SiteVars.LitterfallC[site] += foliarBiomass * 0.47; LitterLayer.PartitionResidue( foliarBiomass, inputDecayValue, SpeciesData.LeafCN[species], SpeciesData.LeafLignin[species], OtherData.StructuralCN, LayerName.Leaf, LayerType.Surface, site); } }
//--------------------------------------------------------------------- // Method for setting the available resorbed N for each cohort. // Amount of resorbed N must be in units of g N m-2. public static void SetResorbedNallocation(ICohort cohort, double resorbedNallocation, ActiveSite site) { int cohortAddYear = GetAddYear(cohort); //PlugIn.ModelCore.UI.WriteLine("SETResorbedNallocation: year={0}, mo={1}, species={2}, cohortAge={3}, cohortAddYear={4}.", PlugIn.ModelCore.CurrentTime, Century.Month, cohort.Species.Name, cohort.Age, cohortAddYear); Dictionary<int, double> cohortDict; double oldResorbedNallocation; // If the dictionary entry exists for the cohort, overwrite it: if (SiteVars.CohortResorbedNallocation[site].TryGetValue(cohort.Species.Index, out cohortDict)) if (cohortDict.TryGetValue(cohortAddYear, out oldResorbedNallocation)) { SiteVars.CohortResorbedNallocation[site][cohort.Species.Index][cohortAddYear] = resorbedNallocation; return; } // If the dictionary does not exist for the cohort, create it: Dictionary<int, double> newEntry = new Dictionary<int, double>(); newEntry.Add(cohortAddYear, resorbedNallocation); if (SiteVars.CohortResorbedNallocation[site].ContainsKey(cohort.Species.Index)) { SiteVars.CohortResorbedNallocation[site][cohort.Species.Index].Add(cohortAddYear, resorbedNallocation); } else { SiteVars.CohortResorbedNallocation[site].Add(cohort.Species.Index, newEntry); } //PlugIn.ModelCore.UI.WriteLine("SET ResorbedNallocation: ResorbedNallocation={0:0.00000}.", resorbedNallocation); return; }
//--------------------------------------------------------------------- // This method replaces the delegate method. It is called every year when // ACT_ANPP is calculated, for each cohort. Therefore, this method is operating at // an ANNUAL time step and separate from the normal extension time step. public static double ReduceCohortGrowth(ICohort cohort, ActiveSite site)//, int siteBiomass) { // PlugIn.ModelCore.UI.WriteLine(" Calculating cohort growth reduction due to insect defoliation..."); double summaryGrowthReduction = 0.0; int sppIndex = cohort.Species.Index; foreach(IInsect insect in PlugIn.ManyInsect) { if(!insect.ActiveOutbreak) continue; int suscIndex = insect.SppTable[sppIndex].Susceptibility - 1; //if (suscIndex < 0) suscIndex = 0; int yearBack = 0; double annualDefoliation = 0.0; if(insect.HostDefoliationByYear[site].ContainsKey(PlugIn.ModelCore.CurrentTime - yearBack)) { // PlugIn.ModelCore.UI.WriteLine("Host Defoliation By Year: Time={0}, suscIndex={1}, spp={2}.", (PlugIn.ModelCore.CurrentTime - yearBack), suscIndex+1, cohort.Species.Name); annualDefoliation += insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime - yearBack][suscIndex]; } double cumulativeDefoliation = annualDefoliation; while(annualDefoliation > 0) { yearBack++; annualDefoliation = 0.0; if(insect.HostDefoliationByYear[site].ContainsKey(PlugIn.ModelCore.CurrentTime - yearBack)) { // PlugIn.ModelCore.UI.WriteLine("Host Defoliation By Year: Time={0}, suscIndex={1}, spp={2}.", (PlugIn.ModelCore.CurrentTime - yearBack), suscIndex+1, cohort.Species.Name); annualDefoliation = insect.HostDefoliationByYear[site][PlugIn.ModelCore.CurrentTime - yearBack][suscIndex]; cumulativeDefoliation += annualDefoliation; } } double slope = insect.SppTable[sppIndex].GrowthReduceSlope; double intercept = insect.SppTable[sppIndex].GrowthReduceIntercept; double growthReduction = 1.0 - (cumulativeDefoliation * slope + intercept); summaryGrowthReduction += growthReduction; // PlugIn.ModelCore.UI.WriteLine("Time={0}, Spp={1}, SummaryGrowthReduction={2:0.00}.", PlugIn.ModelCore.CurrentTime,cohort.Species.Name, summaryGrowthReduction); } if (summaryGrowthReduction > 1.0) // Cannot exceed 100% summaryGrowthReduction = 1.0; if(summaryGrowthReduction > 1.0 || summaryGrowthReduction < 0) { PlugIn.ModelCore.UI.WriteLine("Cohort Total Growth Reduction = {0:0.00}. Site R/C={1}/{2}.", summaryGrowthReduction, site.Location.Row, site.Location.Column); throw new ApplicationException("Error: Total Growth Reduction is not between 1.0 and 0.0"); } return summaryGrowthReduction; }
//--------------------------------------------------------------------- /// <summary> /// Initializes a new instance. /// </summary> public DeathEventArgs(ICohort cohort, ActiveSite site, ExtensionType disturbanceType) { this.cohort = cohort; this.site = site; this.disturbanceType = disturbanceType; }
public void RemoveCohort(Cohort cohort, Landis.SpatialModeling.ActiveSite site) { //ResetSpeciesCohorts(); //Speciescohorts = null; cohorts.Remove(cohort); Cohort.Died(this, cohort, site, null); }
//ISiteCohorts cohorts) //--------------------------------------------------------------------- public static double ComputeBiomass(ActiveSite site) { double total = 0.0; if (SiteVars.Cohorts[site] != null) foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site]) total += ComputeBiomass(speciesCohorts); return total; }
public static bool Algorithm(ISpecies species, ActiveSite site) { return Reproduction.SufficientResources(species, site) && Reproduction.Establish(species, site) && Reproduction.MaturePresent(species, site); //SiteVars.Cohorts[site].IsMaturePresent(species); }
//--------------------------------------------------------------------- public void ApplyTo(ActiveSite site) { if (isDebugEnabled) log.DebugFormat(" Applying LCC {0} to site {1}", GetType().Name, site.Location); cohortHarvest.Cut(site); }
/// <summary> /// Default method for computing how much a cohort is defoliated at /// a site. /// </summary> /// <returns> /// 0% /// </returns> public static double Compute( ActiveSite site, ISpecies species, int cohortBiomass, int siteBiomass) { return 0.0; }
//--------------------------------------------------------------------- /// <summary> /// Cut the trees at a site. /// </summary> public override void Cut(ActiveSite site) { // Use age-only cohort selectors to harvest whole cohorts base.Cut(site); // Then do any partial harvesting with the partial cohort selectors. SiteVars.Cohorts[site].ReduceOrKillBiomassCohorts(this); }
//--------------------------------------------------------------------- public static void WriteTotalsFor(ActiveSite site) { logFile.Write("{0},{1},{2}", Model.Core.CurrentTime, site.Location.Row, site.Location.Column); foreach (ISpecies species in Model.Core.Species) logFile.Write(",{0}", SiteBiomass.Harvested[species]); logFile.WriteLine(); SiteBiomass.ResetHarvestTotals(); }
/// <summary> /// Decomposes Structural Litter /// </summary> public static void Decompose(ActiveSite site) { SiteVars.SurfaceStructural[site].DecomposeStructural(site); SiteVars.SurfaceMetabolic[site].DecomposeMetabolic(site); SiteVars.SoilStructural[site].DecomposeStructural(site); SiteVars.SoilMetabolic[site].DecomposeMetabolic(site); }
//--------------------------------------------------------------------- // This method replaces the delegate method. It is called every year when // ACT_ANPP is calculated, for each cohort. Therefore, this method is operating at // an ANNUAL time step and separate from the normal extension time step. public static double DefoliateCohort(ICohort cohort, ActiveSite site, int siteBiomass) { // This maintains backwards compatibility with succession versions that don't use Biomass Library // but the functions must be sure to provide siteBiomass not cohortBiomass double defoliation = Landis.Extension.Insects.Defoliate.DefoliateCohort(site, cohort.Species, cohort.Biomass, siteBiomass); return defoliation; }
//--------------------------------------------------------------------- /// <summary> /// Raises a Cohort.DeathEvent. /// </summary> public static void Died(object sender, ICohort cohort, ActiveSite site, ExtensionType disturbanceType) { if (DeathEvent != null) DeathEvent(sender, new DeathEventArgs(cohort, site, disturbanceType)); }
//--------------------------------------------------------------------- /// <summary> /// Reduces the biomass of cohorts that have been marked for partial /// reduction. /// </summary> public static void ReduceCohortBiomass(ActiveSite site) { currentSite = site; //PlugIn.ModelCore.Log.WriteLine("ReducingCohortBiomass NOW!"); SiteVars.Cohorts[site].ReduceOrKillBiomassCohorts(singleton); }
//--------------------------------------------------------------------- public static double ComputeWoodBiomass(ActiveSite site) { double woodBiomass = 0; if (SiteVars.Cohorts[site] != null) foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site]) foreach (ICohort cohort in speciesCohorts) woodBiomass += cohort.WoodBiomass; return woodBiomass; }
public static double ComputeBranchBiomass(ActiveSite site) { double branchBiomass = 0; if (SiteVars.Cohorts[site] != null) foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site]) foreach (ICohort cohort in speciesCohorts) branchBiomass += cohort.BranchBiomass; return branchBiomass; }
//--------------------------------------------------------------------- void ICohortHarvest.Cut(ActiveSite site) { if (isDebugEnabled) log.DebugFormat(" {0} is cutting site {1}:", GetType().Name, site.Location); CurrentSite = site; base.Cut(site); }
private static string OutputSiteFileName(ActiveSite site) { string dir = Landis.Extension.Succession.BiomassPnET.InputParametersParser.Names.PNEToutputsites; if (System.IO.Directory.Exists("output/" + dir) == false) { System.IO.Directory.CreateDirectory("output/" + dir); } return "output/" + dir + "/SiteEstData_" + site + Constants.ext; }
//--------------------------------------------------------------------- public void ApplyTo(ActiveSite site) { if (isDebugEnabled) log.DebugFormat(" Applying LCC {0} to site {1}", GetType().Name, site.Location); CurrentSite = site; Cut(site); }