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

        public void CohortPartialMortality(object sender, Landis.Library.BiomassCohorts.PartialDeathEventArgs eventArgs)
        {
            ExtensionType disturbanceType = eventArgs.DisturbanceType;
            ActiveSite    site            = eventArgs.Site;
            double        reduction       = eventArgs.Reduction;

            ICohort cohort = (Landis.Library.LeafBiomassCohorts.ICohort)eventArgs.Cohort;

            float fractionPartialMortality = (float)eventArgs.Reduction;

            //PlugIn.ModelCore.UI.WriteLine("Cohort experienced partial mortality: species={0}, age={1}, wood_biomass={2}, fraction_mortality={3:0.0}.", cohort.Species.Name, cohort.Age, cohort.WoodBiomass, fractionPartialMortality);

            AgeOnlyDisturbances.PoolPercentages cohortReductions = AgeOnlyDisturbances.Module.Parameters.CohortReductions[disturbanceType];

            float foliar = cohort.LeafBiomass * fractionPartialMortality;
            float wood   = cohort.WoodBiomass * fractionPartialMortality;

            float foliarInput = AgeOnlyDisturbances.Events.ReduceInput(foliar, cohortReductions.Foliar, site);
            float woodInput   = AgeOnlyDisturbances.Events.ReduceInput(wood, cohortReductions.Wood, site);

            ForestFloor.AddWoodLitter(woodInput, cohort.Species, site);
            ForestFloor.AddFoliageLitter(foliarInput, cohort.Species, site);

            Roots.AddCoarseRootLitter(woodInput, cohort, cohort.Species, site);  // All of cohorts roots are killed.
            Roots.AddFineRootLitter(foliarInput, cohort, cohort.Species, site);

            //PlugIn.ModelCore.UI.WriteLine("EVENT: Cohort Partial Mortality: species={0}, age={1}, disturbance={2}.", cohort.Species.Name, cohort.Age, disturbanceType);
            //PlugIn.ModelCore.UI.WriteLine("       Cohort Reductions:  Foliar={0:0.00}.  Wood={1:0.00}.", cohortReductions.Foliar, cohortReductions.Wood);
            //PlugIn.ModelCore.UI.WriteLine("       InputB/TotalB:  Foliar={0:0.00}/{1:0.00}, Wood={2:0.0}/{3:0.0}.", foliarInput, foliar, woodInput, wood);

            return;
        }
        /// <summary>
        /// Summarize cohort C&N for output.
        /// </summary>
        private static void CalculateCohortCN(ActiveSite site, ICohort cohort)
        {
            ISpecies species = cohort.Species;

            double leafC = cohort.LeafBiomass * 0.47;
            double woodC = cohort.WoodBiomass * 0.47;

            double fRootC = Roots.CalculateFineRoot(cohort, leafC);
            double cRootC = Roots.CalculateCoarseRoot(cohort, woodC);

            double totalC = leafC + woodC + fRootC + cRootC;

            double leafN  = leafC / (double)SpeciesData.LeafCN[species];
            double woodN  = woodC / (double)SpeciesData.WoodCN[species];
            double cRootN = cRootC / (double)SpeciesData.CoarseRootCN[species];
            double fRootN = fRootC / (double)SpeciesData.FineRootCN[species];

            //double totalN = woodN + cRootN + leafN + fRootN;

            //PlugIn.ModelCore.UI.WriteLine("month={0}, species={1}, leafB={2:0.0}, leafC={3:0.00}, leafN={4:0.0}, woodB={5:0.0}, woodC={6:0.000}, woodN={7:0.0}", Month, cohort.Species.Name, cohort.LeafBiomass, leafC, leafN, cohort.WoodBiomass, woodC, woodN);

            SiteVars.CohortLeafC[site]  += leafC;
            SiteVars.CohortFRootC[site] += fRootC;
            SiteVars.CohortLeafN[site]  += leafN;
            SiteVars.CohortFRootN[site] += fRootN;
            SiteVars.CohortWoodC[site]  += woodC;
            SiteVars.CohortCRootC[site] += cRootC;
            SiteVars.CohortWoodN[site]  += woodN;
            SiteVars.CohortCRootN[site] += cRootN;

            return;
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Calculates cohort N demand depending upon how much N would be removed through growth (ANPP) of leaves, wood, coarse roots and fine roots.
        /// Demand is then used to determine the amount of N that a cohort "wants".
        /// </summary>
        public static double CalculateCohortNDemand(ISpecies species, ActiveSite site, ICohort cohort, double[] ANPP)
        {
            if (ANPP[1] <= 0.0)
            {
                return(0.0);
            }
            //return 0.01;


            if (SpeciesData.NFixer[species])  // We fix our own N!
            {
                return(0.0);
            }

            double ANPPwood       = 0.0;
            double ANPPleaf       = 0.0;
            double ANPPcoarseRoot = 0.0;
            double ANPPfineRoot   = 0.0;
            double woodN          = 0.0;
            double coarseRootN    = 0.0;
            double leafN          = 0.0;
            double fineRootN      = 0.0;

            if (ANPP[0] > 0.0)  // Wood
            {
                ANPPwood       = ANPP[0];
                ANPPcoarseRoot = Roots.CalculateCoarseRoot(cohort, ANPPwood);

                woodN       = ANPPwood * 0.47 / SpeciesData.WoodCN[species];
                coarseRootN = ANPPcoarseRoot * 0.47 / SpeciesData.CoarseRootCN[species];
            }

            if (ANPP[1] > 0.0)  // Leaf
            {
                ANPPleaf     = ANPP[1];
                ANPPfineRoot = Roots.CalculateFineRoot(cohort, ANPPleaf);

                leafN     = ANPPleaf * 0.47 / SpeciesData.LeafCN[species];
                fineRootN = ANPPfineRoot * 0.47 / SpeciesData.FineRootCN[species];
            }

            double totalANPP_C = (ANPPleaf + ANPPwood + ANPPcoarseRoot + ANPPfineRoot) * 0.47;
            double Ndemand     = leafN + woodN + coarseRootN + fineRootN;

            if (Ndemand < 0.0)
            {
                PlugIn.ModelCore.UI.WriteLine("   ERROR:  TotalANPP-C={0:0.00} Nreduction={1:0.00}.", totalANPP_C, Ndemand);
                throw new ApplicationException("Error: N Reduction is < 0.  See AvailableN.cs");
            }


            return(Ndemand);
        }
Exemple #4
0
        //---------------------------------------------------------------------
        /// <summary>
        /// Summarize NPP
        /// </summary>
        private static void CalculateNPPcarbon(ActiveSite site, ICohort cohort, double[] AGNPP)
        {
            double NPPwood = (double)AGNPP[0] * 0.47;
            double NPPleaf = (double)AGNPP[1] * 0.47;

            double NPPcoarseRoot = Roots.CalculateCoarseRoot(cohort, NPPwood);
            double NPPfineRoot   = Roots.CalculateFineRoot(cohort, NPPleaf);

            if (Double.IsNaN(NPPwood) || Double.IsNaN(NPPleaf) || Double.IsNaN(NPPcoarseRoot) || Double.IsNaN(NPPfineRoot))
            {
                PlugIn.ModelCore.UI.WriteLine("  EITHER WOOD or LEAF NPP or COARSE ROOT or FINE ROOT = NaN!  Will set to zero.");
                PlugIn.ModelCore.UI.WriteLine("  Yr={0},Mo={1}.     WoodNPP={0}, LeafNPP={1}, CRootNPP={2}, FRootNPP={3}.", NPPwood, NPPleaf, NPPcoarseRoot, NPPfineRoot);
                if (Double.IsNaN(NPPleaf))
                {
                    NPPleaf = 0.0;
                }
                if (Double.IsNaN(NPPwood))
                {
                    NPPwood = 0.0;
                }
                if (Double.IsNaN(NPPcoarseRoot))
                {
                    NPPcoarseRoot = 0.0;
                }
                if (Double.IsNaN(NPPfineRoot))
                {
                    NPPfineRoot = 0.0;
                }
            }


            SiteVars.AGNPPcarbon[site] += NPPwood + NPPleaf;
            SiteVars.BGNPPcarbon[site] += NPPcoarseRoot + NPPfineRoot;
            SiteVars.MonthlyAGNPPcarbon[site][Main.Month] += NPPwood + NPPleaf;
            SiteVars.MonthlyBGNPPcarbon[site][Main.Month] += NPPcoarseRoot + NPPfineRoot;

            if (PlugIn.ModelCore.CurrentTime > 0 && OtherData.CalibrateMode)
            {
                Outputs.CalibrateLog.Write("{0:0.00},{1:0.00},", NPPwood, NPPleaf);
            }
        }
        //---------------------------------------------------------------------
        public void CohortDied(object sender,
                               Landis.Library.BiomassCohorts.DeathEventArgs eventArgs)
        {
            ExtensionType disturbanceType = eventArgs.DisturbanceType;
            ActiveSite    site            = eventArgs.Site;

            ICohort cohort = (Landis.Library.LeafBiomassCohorts.ICohort)eventArgs.Cohort;
            double  foliar = (double)cohort.LeafBiomass;

            double wood = (double)cohort.WoodBiomass;

            PlugIn.ModelCore.UI.WriteLine("Cohort Died: species={0}, age={1}, biomass={2}, foliage={3}.", cohort.Species.Name, cohort.Age, cohort.Biomass, foliar);

            if (disturbanceType == null)
            {
                //PlugIn.ModelCore.UI.WriteLine("NO EVENT: Cohort Died: species={0}, age={1}, disturbance={2}.", cohort.Species.Name, cohort.Age, eventArgs.DisturbanceType);

                ForestFloor.AddWoodLitter(wood, cohort.Species, eventArgs.Site);
                ForestFloor.AddFoliageLitter(foliar, cohort.Species, eventArgs.Site);

                Roots.AddCoarseRootLitter(wood, cohort, cohort.Species, eventArgs.Site);
                Roots.AddFineRootLitter(foliar, cohort, cohort.Species, eventArgs.Site);
            }

            if (disturbanceType != null)
            {
                //PlugIn.ModelCore.UI.WriteLine("DISTURBANCE EVENT: Cohort Died: species={0}, age={1}, disturbance={2}.", cohort.Species.Name, cohort.Age, eventArgs.DisturbanceType);

                Disturbed[site] = true;
                if (disturbanceType.IsMemberOf("disturbance:fire"))
                {
                    Landis.Library.Succession.Reproduction.CheckForPostFireRegen(eventArgs.Cohort, site);
                }
                else
                {
                    Landis.Library.Succession.Reproduction.CheckForResprouting(eventArgs.Cohort, site);
                }
            }
        }
Exemple #6
0
        //---------------------------------------------------------------------

        private void UpdateDeadBiomass(ICohort cohort, ActiveSite site, double[] totalMortality)
        {
            double mortality_wood    = (double)totalMortality[0];
            double mortality_nonwood = (double)totalMortality[1];

            //  Add mortality to dead biomass pools.
            //  Coarse root mortality is assumed proportional to aboveground woody mortality
            //    mass is assumed 25% of aboveground wood (White et al. 2000, Niklas & Enquist 2002)
            if (mortality_wood > 0.0)
            {
                ForestFloor.AddWoodLitter(mortality_wood, cohort.Species, site);
                Roots.AddCoarseRootLitter(mortality_wood, cohort, cohort.Species, site);
            }

            if (mortality_nonwood > 0.0)
            {
                AvailableN.AddResorbedN(cohort, totalMortality[1], site); //ignoring input from scorching, which is rare, but not resorbed.
                ForestFloor.AddResorbedFoliageLitter(mortality_nonwood, cohort.Species, site);
                Roots.AddFineRootLitter(mortality_nonwood, cohort, cohort.Species, site);
            }

            return;
        }
        //---------------------------------------------------------------------
        // Method for calculating Mineral N allocation, called from Main.cs Run method before calling Grow
        // Iterates through cohorts, assigning each a portion of mineral N based on coarse root biomass.  Uses an exponential function to "distribute"
        // the N more evenly between spp. so that the ones with the most woody biomass don't get all the N (L122).

        public static void CalculateMineralNfraction(Site site)
        {
            AvailableN.CohortMineralNfraction = new Dictionary <int, Dictionary <int, double> >();
            double NAllocTotal = 0.0;

            foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
            {
                foreach (ICohort cohort in speciesCohorts)
                {
                    int cohortAddYear = GetAddYear(cohort);
                    //PlugIn.ModelCore.UI.WriteLine("CALCMineralNfraction: year={0}, mo={1}, species={2}, cohortAge={3}, cohortAddYear={4}.", PlugIn.ModelCore.CurrentTime, Main.Month, cohort.Species.Name, cohort.Age, cohortAddYear);

                    //Nallocation is a measure of how much N a cohort can gather relative to other cohorts
                    //double Nallocation = Roots.CalculateFineRoot(cohort.LeafBiomass);
                    double Nallocation = 1 - Math.Exp((-Roots.CalculateCoarseRoot(cohort, cohort.WoodBiomass) * 0.02));

                    if (Nallocation <= 0.0) //PlugIn.ModelCore.CurrentTime == 0)
                    {
                        Nallocation = Math.Max(Nallocation, cohort.WoodBiomass * 0.01);
                    }

                    NAllocTotal += Nallocation;
                    Dictionary <int, double> newEntry = new Dictionary <int, double>();
                    newEntry.Add(cohortAddYear, Nallocation);

                    if (CohortMineralNfraction.ContainsKey(cohort.Species.Index))
                    {
                        //CohortMineralNfraction[cohort.Species.Index].Add(cohortAddYear, Nallocation);

                        // option 1: regardless of whether cohortAddYear already exists, create (or replace) the new value
                        //CohortMineralNfraction[cohort.Species.Index][cohortAddYear] = Nallocation;
                        // end of option 1

                        // option 2: if the cohortAddYear already exists, add the new value to the existing one
                        //double currentNallocation;
                        //CohortMineralNfraction[cohort.Species.Index].TryGetValue(cohortAddYear, out currentNallocation);        // currentNallocation will be set to 0.0 if the cohortAddYear key does not exist

                        //CohortMineralNfraction[cohort.Species.Index][cohortAddYear] = currentNallocation + Nallocation;
                        // end of option 2
                        //if key is already present, then don't trigger an error.
                        if (!CohortMineralNfraction[cohort.Species.Index].ContainsKey(cohortAddYear))
                        {
                            CohortMineralNfraction[cohort.Species.Index][cohortAddYear] = Nallocation;
                        }
                    }
                    else
                    {
                        CohortMineralNfraction.Add(cohort.Species.Index, newEntry);
                    }
                }
            }

            // Next relativize
            foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site])
            {
                //PlugIn.ModelCore.UI.WriteLine(" SpeciesCohorts = {0}", speciesCohorts.Species.Name);
                foreach (ICohort cohort in speciesCohorts)
                {
                    int    cohortAddYear       = GetAddYear(cohort);
                    double Nallocation         = CohortMineralNfraction[cohort.Species.Index][cohortAddYear];
                    double relativeNallocation = Nallocation / NAllocTotal;
                    CohortMineralNfraction[cohort.Species.Index][cohortAddYear] = relativeNallocation;

                    if (Double.IsNaN(relativeNallocation) || Double.IsNaN(Nallocation) || Double.IsNaN(NAllocTotal))
                    {
                        PlugIn.ModelCore.UI.WriteLine("  N ALLOCATION CALCULATION = NaN!  ");
                        PlugIn.ModelCore.UI.WriteLine("  Nallocation={0:0.00}, NAllocTotal={1:0.00}, relativeNallocation={2:0.00}.", Nallocation, NAllocTotal, relativeNallocation);
                        PlugIn.ModelCore.UI.WriteLine("  Wood={0:0.00}, Leaf={1:0.00}.", cohort.WoodBiomass, cohort.LeafBiomass);
                    }
                }
            }
        }