//---------------------------------------------------------------------
        /// <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;
        }
 public void NoCohorts_Grow()
 {
     SiteCohorts cohorts = new SiteCohorts();
     mockCalculator.CountCalled = 0;
     Util.Grow(cohorts, 5, activeSite, false);
     Assert.AreEqual(0, mockCalculator.CountCalled);
 }
 //---------------------------------------------------------------------
 private InitialBiomass(SiteCohorts cohorts,
                        Landis.Library.Biomass.Pool deadWoodyPool,
                        Landis.Library.Biomass.Pool deadNonWoodyPool)
 {
     this.cohorts = cohorts;
     this.deadWoodyPool = deadWoodyPool;
     this.deadNonWoodyPool = deadNonWoodyPool;
 }
 //---------------------------------------------------------------------
 private InitialBiomass(SiteCohorts cohorts,
     Dead.Pool   deadWoodyPool,
     Dead.Pool   deadNonWoodyPool)
 {
     this.cohorts = cohorts;
     this.deadWoodyPool = deadWoodyPool;
     this.deadNonWoodyPool = deadNonWoodyPool;
 }
示例#5
0
 	//---------------------------------------------------------------------
 
 	/// <summary>
 	/// Grows all cohorts at a site for a number of years.
 	/// </summary>
 	public static void Grow(SiteCohorts cohorts,
 	                        int         years,
 	                        ActiveSite  site,
 	                        bool        isSuccessionTimestep)
 	{
         for (int y = 1; y <= years; ++y)
             cohorts.Grow(site, (y == years && isSuccessionTimestep));
 	}
        public void TestInit()
        {
            List<ISpeciesCohorts> speciesCohortList = new List<ISpeciesCohorts>();
            speciesCohortList.Add(MakeCohorts(abiebals, 30, 40, 50, 150, 170));
            speciesCohortList.Add(MakeCohorts(betualle, 100, 120, 280, 300));
            siteCohorts = new SiteCohorts(speciesCohortList);

            deadCohorts.Clear();
        }
        public void SingleCohort()
        {
            SiteCohorts cohorts = new SiteCohorts();
            const ushort initialBiomass = 300;
            cohorts.AddNewCohort(abiebals, initialBiomass);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] { 1, initialBiomass };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
示例#8
0
 /// <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)
 {
     for (int y = 1; y <= years; ++y) {
         cohorts.Grow(site, (y == years && isSuccessionTimestep));
         Dead.Pools.Woody[site].Decompose();
         Dead.Pools.NonWoody[site].Decompose();
     }
 }
        public void SingleCohort()
        {
            SiteCohorts cohorts = new SiteCohorts();
            Assert.AreEqual(0, cohorts.TotalBiomass);

            const int initialBiomass = 300;
            cohorts.AddNewCohort(abiebals, initialBiomass);
            Assert.AreEqual(initialBiomass, cohorts.TotalBiomass);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new int [] { 1, initialBiomass };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Computes the actual biomass at a site.  The biomass is the total
        /// of all the site's cohorts except young ones.  The total is limited
        /// to being no more than the site's maximum biomass less the previous
        /// year's mortality at the site.
        /// </summary>
        public static double ActualSiteBiomass(SiteCohorts    siteCohorts,
            ActiveSite     site,
            out IEcoregion ecoregion)
        {
            int youngBiomass;
            int totalBiomass = Cohorts.ComputeBiomass(siteCohorts, out youngBiomass);
            double B_ACT = totalBiomass - youngBiomass;

            int lastMortality = siteCohorts.PrevYearMortality;
            ecoregion = Model.Core.Ecoregion[site];
            B_ACT = Math.Min( B_MAX[ecoregion] - lastMortality, B_ACT);

            return B_ACT;
        }
示例#11
0
        public void SingleCohort()
        {
            SiteCohorts cohorts = new SiteCohorts();

            Assert.AreEqual(0, cohorts.TotalBiomass);

            const ushort initialBiomass = 300;

            cohorts.AddNewCohort(abiebals, initialBiomass);
            Assert.AreEqual(initialBiomass, cohorts.TotalBiomass);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] { 1, initialBiomass };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
 //---------------------------------------------------------------------
 private InitialBiomass(SiteCohorts cohorts,
                        List<PoolD> litterPool,
                        PoolD woodyDebrisPool,
                        List<PoolD> deadFRootsPool,
                        Pool fineRootsPool,
                        Pool coarseRootsPool,
                        Charcoal charcoalPool)
 {
     this.cohorts = cohorts;
     this.litterPool = litterPool;
     this.woodyDebrisPool = woodyDebrisPool;
     this.deadFRootsPool = deadFRootsPool;
     this.fineRootsPool = fineRootsPool;
     this.coarseRootsPool = coarseRootsPool;
     this.charcoalPool = charcoalPool;
 }
示例#13
0
        public void Every2ndCohort()
        {
            disturbance.Damage = disturbance.Every2ndCohort;
            SiteCohorts siteCohorts = initialSiteCohorts.Clone();

            ((Landis.AgeCohort.ISiteCohorts)siteCohorts).DamageBy(disturbance);

            CheckCohorts(siteCohorts[abiebals], 30, 50, 170);
            CheckCohorts(siteCohorts[betualle], 100, 280);

            CheckDeadCohorts(abiebals, 40, 150);
            CheckDeadCohorts(betualle, 120, 300);

            Assert.AreEqual(initialSiteCohorts.TotalBiomass - deadCohortsBiomass,
                            siteCohorts.TotalBiomass);
        }
示例#14
0
        private int GetMaxAge(SiteCohorts Cohorts)
        {
            int maxage = int.MinValue;

            foreach (ISpeciesCohorts spc in Cohorts)
            {
                foreach (ICohort cohort in spc)
                {
                    if (cohort.Age > maxage)
                    {
                        maxage = cohort.Age;
                    }
                }
            }
            return(maxage);
        }
		public void SingleCohort_LongevityReached()
		{
		    SiteCohorts cohorts = new SiteCohorts();
		    const ushort initialBiomass = 300;
		    cohorts.AddNewCohort(poputrem, initialBiomass);

		    mockCalculator.CountCalled = 0;
		    mockCalculator.Change = 1;

		    expectedSite = activeSite;
		    deadCohorts.Clear();

		    //  Repeatedly grow for succession timesteps until longevity
		    //  reached.
		    int time = 0;
		    do {
		         time += successionTimestep;
		        cohorts.Grow(successionTimestep, activeSite, true);
		    } while (time <= poputrem.Longevity);

		    expectedCohorts.Clear();
		    Util.CheckCohorts(expectedCohorts, cohorts);

		    //  Calculator called L times where L is longevity.  Inituitively,
		    //  one would think since initial cohort's age is 1, it'd only take
		    //  L-1 times to get to the max age (= L).  So the calculator
		    //  should be called L-1 times.  But the combining of young cohorts
		    //  at the first succession timestep (t_succ = 20) results in the
		    //  calculator being called twice with cohort age = t_succ-1 (19).
		    //  At the end of year 19, the cohort's age is 20 and the
		    //  calculator has been called 19 times.  But at the start of year
		    //  20, the combine-young-cohorts operation is done because it's a
		    //  succession timestep.  The combine operation takes all the young
		    //  cohorts (age <= t_succ = 20) and replaces them with one cohort
		    //  with age = t_succ-1 (= 19).  This ensures that after the growth
		    //  phase, the cohort's age will be t_succ (20).  So the growth
		    //  phase of year 20 calls the calculator for the 20th time with
		    //  cohort age 19.
		    Assert.AreEqual(poputrem.Longevity, mockCalculator.CountCalled);

		    Assert.AreEqual(1, deadCohorts.Count);
		    ICohort deadCohort = deadCohorts[0];
		    Assert.AreEqual(poputrem, deadCohort.Species);
		    Assert.AreEqual(poputrem.Longevity, deadCohort.Age);
		    Assert.AreEqual(initialBiomass + (poputrem.Longevity * mockCalculator.Change),
		                    deadCohort.Biomass);
		}
        public SiteConditions(ActiveSite site, ICommunity initialCommunity)
        {
            cohorts = new SiteCohorts();

            canopy = new Canopy();
            if (PlugIn.HasSiteOutput[site] == true)
            {
                siteoutput = new SiteOutput(site);
                estoutput = new EstablishmentOutput(site);
            }

            this.site = site;

            foreach (ISpecies spc in PlugIn.modelCore.Species)
            {
                deadcohortages[spc] = new List<int>();
            }

            uint key = ComputeKey(initialCommunity.MapCode, PlugIn.ModelCore.Ecoregion[site].MapCode);

            SiteConditions s = GetFromKey(key);

            if (s != null) return;

            //  If we don't have a sorted list of age cohorts for the initial
            //  community, make the list

            List<Landis.Library.AgeOnlyCohorts.ICohort> sortedAgeCohorts;
            if (!sortedCohorts.TryGetValue(initialCommunity.MapCode, out sortedAgeCohorts))
            {
                sortedAgeCohorts = PlugIn.RankCohortAgesOldToYoung(initialCommunity.Cohorts);
                sortedCohorts[initialCommunity.MapCode] = sortedAgeCohorts;
            }
            hydrology = new Hydrology(PlugIn.modelCore.Ecoregion[site]);
            forestfloor = new ForestFloor();
            cohorts = new SiteCohorts();
            establishment = new EstablishmentProbability(site);

            if (sortedAgeCohorts.Count == 0) return;

            //PlugIn.ModelCore.UI.WriteLine("Making Biomass Cohorts "+ site);
            BiomassSpinUp(sortedAgeCohorts, site);

            initialSites[key] = this;
            return;
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Computes the actual biomass at a site.  The biomass is the total
        /// of all the site's cohorts except young ones.  The total is limited
        /// to being no more than the site's maximum biomass less the previous
        /// year's mortality at the site.
        /// </summary>
        public static double ActualSiteBiomass(SiteCohorts siteCohorts,
                                               ActiveSite site)
        {
            IEcoregion ecoregion = Model.Core.Ecoregion[site];

            if (siteCohorts == null)
                return 0.0;

            int youngBiomass;
            int totalBiomass = Landis.Biomass.Cohorts.ComputeBiomass(siteCohorts, out youngBiomass);
            double B_ACT = totalBiomass - youngBiomass;

            int lastMortality = (int) SiteVars.PrevYearMortality[site]; //siteCohorts.PrevYearMortality;
            B_ACT = System.Math.Min(SpeciesData.B_MAX[ecoregion] - lastMortality, B_ACT);

            return B_ACT;
        }
示例#18
0
        //---------------------------------------------------------------------

        //---------------------------------------------------------------------
        /// <summary>
        /// Reads the initial communities map, finds all unique site keys, and sets aside sites to process first and second
        /// </summary>
        private void ProcessInitialCommunitiesMap(string initialCommunitiesMap,
                                                  Landis.Library.InitialCommunities.IDataset communities, ref List <ActiveSite> processFirst,
                                                  ref List <ActiveSite> processSecond)
        {
            IInputRaster <uintPixel>      map        = ModelCore.OpenRaster <uintPixel>(initialCommunitiesMap);
            Dictionary <uint, ActiveSite> uniqueKeys = new Dictionary <uint, ActiveSite>();

            using (map)
            {
                uintPixel pixel = map.BufferPixel;
                foreach (Site site in ModelCore.Landscape.AllSites)
                {
                    map.ReadBufferPixel();
                    uint mapCode = pixel.MapCode.Value;
                    if (!site.IsActive)
                    {
                        continue;
                    }

                    ActiveSite activeSite       = (ActiveSite)site;
                    var        initialCommunity = communities.Find(mapCode);
                    if (initialCommunity == null)
                    {
                        throw new ApplicationException(string.Format("Unknown map code for initial community: {0}", mapCode));
                    }

                    sitesAndCommunities.Add(activeSite, initialCommunity);
                    uint key = SiteCohorts.ComputeKey((ushort)initialCommunity.MapCode, Globals.ModelCore.Ecoregion[site].MapCode);

                    if (!uniqueKeys.ContainsKey(key))
                    {
                        uniqueKeys.Add(key, activeSite);
                        processFirst.Add(activeSite);
                    }
                    else
                    {
                        processSecond.Add(activeSite);
                    }

                    if (!allKeys.ContainsKey(activeSite))
                    {
                        allKeys.Add(activeSite, key);
                    }
                }
            }
        }
        //---------------------------------------------------------------------

        private void MakeAndCheckCohorts(int timestep)
        {
            //  All cohort ages are multiples of 10, and this code requires
            //  that the given timestep divides 10 evenly (to mimic binning
            //  process of the initial communities).
            Assert.IsTrue(10 % timestep == 0);

            isTimestep1 = (timestep == 1);
            Landis.Biomass.Cohorts.Initialize(timestep, mockCalculator);
            InitialBiomass.Initialize(timestep);
            SiteCohorts cohorts = InitialBiomass.MakeBiomassCohorts(ageCohorts,
                                                                    activeSite,
                                                                    ComputeInitialBiomass);

            CheckCohorts(cohorts[abiebals], abiebalsAges);
            CheckCohorts(cohorts[betualle], betualleAges);
        }
示例#20
0
        public void AbiebalsOldest()
        {
            disturbance.Damage          = disturbance.OldestOfSelectedSpecies;
            disturbance.SelectedSpecies = abiebals;
            SiteCohorts siteCohorts = initialSiteCohorts.Clone();

            ((Landis.AgeCohort.ISiteCohorts)siteCohorts).DamageBy(disturbance);

            CheckCohorts(siteCohorts[abiebals], 30, 40, 50, 150);
            CheckCohorts(siteCohorts[betualle], 100, 120, 280, 300);

            CheckDeadCohorts(abiebals, 170);
            CheckDeadCohorts(betualle);

            Assert.AreEqual(initialSiteCohorts.TotalBiomass - deadCohortsBiomass,
                            siteCohorts.TotalBiomass);
        }
        //---------------------------------------------------------------------
        /// <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)
        {
            for (int y = 1; y <= years; ++y) {

                // Calculate competition for each cohort
                CohortBiomass.CalculateCompetition(cohorts);

                CohortBiomass.SubYear = y;

                cohorts.Grow(site, (y == years && isSuccessionTimestep));
                SiteVars.WoodyDebris[site].Decompose();
                SiteVars.Litter[site].Decompose();
            }
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Computes the initial biomass for a cohort at a site.
        /// </summary>
        public static float[] InitialBiomass(SiteCohorts siteCohorts,
            ActiveSite  site, ISpecies species)
        {
            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];

            double leafFrac = FunctionalType.Table[SpeciesData.FuncType[species]].FCFRACleaf;
            double Nreduction = 0.0;

            double B_ACT = SiteVars.ActualSiteBiomass(site);
            double B_MAX = SpeciesData.B_MAX_Spp[species][ecoregion];//B_MAX[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, 1.0);

            double initialLeafB = initialBiomass * leafFrac;
            double initialWoodB = initialBiomass * (1.0 - leafFrac);
            double[] initialB = new double[2]{initialWoodB, 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);

            // Note:  The following if statement is critical for ensuring that young cohorts
            // get established properly.
            if (SiteVars.MineralN[site] <= 0 || initialBiomass < 5.0)
            {
                initialBiomass = Math.Min(initialBiomass, 5.0);
                initialB[0] = initialBiomass * (1.0 - leafFrac);
                initialB[1] = initialBiomass * leafFrac;
            }

            Nreduction = AvailableN.CohortUptakeAvailableN(species, site, initialB);

            SiteVars.MineralN[site] -= Nreduction;

            float[] initialWoodLeafBiomass = new float[2]{(float) initialB[0], (float) initialB[1]};
            //float[] initialWoodLeafBiomass = new float[2]{(float) initialBiomass, 0.0F};

            return initialWoodLeafBiomass;
        }
        public void Grow()
        {
            SiteCohorts cohorts = new SiteCohorts();
            const ushort initialBiomass = 35;
            cohorts.AddNewCohort(abiebals, initialBiomass);

            mockCalculator.CountCalled = 0;
            mockCalculator.Change = 8;

            cohorts.Grow(activeSite, true);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] {
                //  age  biomass
                     2,   (ushort) (initialBiomass + mockCalculator.Change)
            };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
        //---------------------------------------------------------------------
        private InitialBiomass(
            SiteCohorts cohorts,
            
            Layer surfaceDeadWood,
            Layer surfaceStructural,
            Layer surfaceMetabolic,
            
            Layer soilDeadWood,
            Layer soilStructural,
            Layer soilMetabolic,
            
            Layer som1surface,
            Layer som1soil,
            Layer som2,
            Layer som3,
            
            double mineralN,
            double cohortLeafC,
            double cohortLeafN,
            double cohortWoodC,
            double cohortWoodN
            )
        {
            this.cohorts = cohorts;

            this.surfaceDeadWood = surfaceDeadWood;
            this.surfaceStructural = surfaceStructural;
            this.surfaceMetabolic = surfaceMetabolic;

            this.soilDeadWood = soilDeadWood;
            this.soilStructural = soilStructural;
            this.soilMetabolic = soilMetabolic;

            this.som1surface = som1surface;
            this.som1soil = som1soil;
            this.som2 = som2;
            this.som3 = som3;

            this.mineralN = mineralN;
            this.cohortLeafC = cohortLeafC;
            this.cohortLeafN = cohortLeafN;
            this.cohortWoodC = cohortWoodC;
            this.cohortWoodN = cohortWoodN;
        }
示例#25
0
        public void Grow()
        {
            SiteCohorts  cohorts        = new SiteCohorts();
            const ushort initialBiomass = 35;

            cohorts.AddNewCohort(abiebals, initialBiomass);

            mockCalculator.CountCalled = 0;
            mockCalculator.Change      = 8;

            cohorts.Grow(activeSite, true);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] {
                //  age  biomass
                2, (ushort)(initialBiomass + mockCalculator.Change)
            };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
示例#26
0
        public void CombineYoungCohorts()
        {
            SiteCohorts cohorts = new SiteCohorts();

            int[] initialBiomass = new int[] { 300, 700 };
            cohorts.AddNewCohort(abiebals, initialBiomass[0]);
            Assert.AreEqual(initialBiomass[0], cohorts.TotalBiomass);

            //  Grow 1st cohort for 4 years, adding 10 to its biomass per year
            mockCalculator.CountCalled = 0;
            mockCalculator.Change      = 10;
            Util.Grow(cohorts, 4, activeSite, false);

            Assert.AreEqual(4, mockCalculator.CountCalled);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new int[] {
                5, (int)(300 + 4 * mockCalculator.Change)
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            //  Add 2nd cohort and then grow both cohorts 6 more years up to
            //  a succession timestep
            cohorts.AddNewCohort(abiebals, initialBiomass[1]);
            mockCalculator.CountCalled = 0;
            Util.Grow(cohorts, 6, activeSite, true);

            //  ComputeChange for both cohorts for 5 years, then combine them,
            //  and then one time for the combined cohort
            Assert.AreEqual(5 * 2 + 1, mockCalculator.CountCalled);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new int[] {
                successionTimestep,
                (int)
                (300 + (4 + 5) * mockCalculator.Change     // first cohort before combining
                 + 700 + 5 * mockCalculator.Change         // 2nd cohort before combining
                 + mockCalculator.Change)                  // growth after combining
            };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
示例#27
0
        //---------------------------------------------------------------------

        private void CreateInitialCohorts()
        {
            ushort[] abiebalsAges = new ushort[] { 30, 40, 50, 150, 170 };
            ushort[] betualleAges = new ushort[] { 100, 120, 280, 300 };

            //  Work with ages from oldest to youngest
            System.Array.Sort(abiebalsAges, Landis.AgeCohort.Util.WhichIsOlder);
            System.Array.Sort(betualleAges, Landis.AgeCohort.Util.WhichIsOlder);

            //  Loop through succession timesteps from the time when the
            //  oldest cohort would have been added to site (= -{its age}) to
            //  the present (time = 0).  Each cohort is added to the site
            //  when time = -{its age}.
            initialSiteCohorts = new SiteCohorts();
            const int     initialBiomass   = 55;
            List <ushort> abiebalsAgesLeft = new List <ushort>(abiebalsAges);
            List <ushort> betualleAgesLeft = new List <ushort>(betualleAges);
            ushort        maxAge           = System.Math.Max(abiebalsAgesLeft[0], betualleAgesLeft[0]);

            for (int time = -maxAge; time <= 0; time += successionTimestep)
            {
                Util.Grow(initialSiteCohorts, successionTimestep, activeSite, true);
                if (abiebalsAgesLeft.Count > 0)
                {
                    if (time == -(abiebalsAgesLeft[0]))
                    {
                        initialSiteCohorts.AddNewCohort(abiebals, initialBiomass);
                        abiebalsAgesLeft.RemoveAt(0);
                    }
                }
                if (betualleAgesLeft.Count > 0)
                {
                    if (time == -(betualleAgesLeft[0]))
                    {
                        initialSiteCohorts.AddNewCohort(betualle, initialBiomass);
                        betualleAgesLeft.RemoveAt(0);
                    }
                }
            }
        }
示例#28
0
        //---------------------------------------------------------------------

        /// <summary>
        /// Computes the initial biomass for a cohort at a site.
        /// </summary>
        public static int InitialBiomass(ISpecies species,
                                         SiteCohorts siteCohorts,
                                         ActiveSite site)
        {
            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];
            //double B_ACT = ActualSiteBiomass(siteCohorts, site, out ecoregion);

            double B_ACT = 0.0;

            //Biomass code
            // Copied from Library.BiomassCohorts.Cohorts.cs, but added restriction that age > 1 (required when running 1-year timestep)
            foreach (ISpeciesCohorts speciesCohorts in siteCohorts)
            {
                foreach (ICohort cohort in speciesCohorts)
                {
                    if ((cohort.Age > 1))
                    {
                        B_ACT += cohort.Biomass;
                    }
                }
            }
            //if (siteCohorts != null)
            //    B_ACT = (double)Cohorts.ComputeNonYoungBiomass(siteCohorts);  //CForCS

            double maxBiomass = SpeciesData.B_MAX_Spp[species][ecoregion];
            double maxANPP    = SpeciesData.ANPP_MAX_Spp[species][ecoregion];

            //  Initial biomass exponentially declines in response to competition.
            //double initialBiomass = 0.02 * maxBiomass * Math.Exp(-1.6 * B_ACT / EcoregionData.B_MAX[ecoregion]);  //ForCS
            double initialBiomass = maxANPP * Math.Exp(-1.6 * B_ACT / EcoregionData.B_MAX[ecoregion]);     //Biomass

            // Initial biomass cannot be greater than maxANPP
            initialBiomass = Math.Min(maxANPP, initialBiomass);

            //  Initial biomass cannot be less than 2.  C. Dymond issue from August 2016
            initialBiomass = Math.Max(2.0, initialBiomass);

            return((int)initialBiomass);
        }
		public void CombineYoungCohorts()
		{
		    SiteCohorts cohorts = new SiteCohorts();
		    ushort[] initialBiomass = new ushort[] { 300, 700 };
		    cohorts.AddNewCohort(abiebals, initialBiomass[0]);

		    //  Grow 1st cohort for 4 years, adding 10 to its biomass per year
		    mockCalculator.CountCalled = 0;
		    mockCalculator.Change = 10;
		    cohorts.Grow(4, activeSite, false);

		    Assert.AreEqual(4, mockCalculator.CountCalled);

		    expectedCohorts.Clear();
		    expectedCohorts[abiebals] = new ushort[] {
		        5, (ushort) (300 + 4 * mockCalculator.Change)
		    };
		    Util.CheckCohorts(expectedCohorts, cohorts);

		    //  Add 2nd cohort and then grow both cohorts 6 more years up to
		    //  a succession timestep
		    cohorts.AddNewCohort(abiebals, initialBiomass[1]);
     	    mockCalculator.CountCalled = 0;
		    cohorts.Grow(6, activeSite, true);

		    //  ComputeChange for both cohorts for 5 years, then combine them,
		    //  and then one time for the combined cohort
		    Assert.AreEqual(5 * 2 + 1, mockCalculator.CountCalled);

		    expectedCohorts.Clear();
		    expectedCohorts[abiebals] = new ushort[] {
		        successionTimestep,
		        (ushort)
		            (300 + (4 + 5) * mockCalculator.Change // first cohort before combining
		             + 700 + 5 * mockCalculator.Change     // 2nd cohort before combining
		             + mockCalculator.Change)              // growth after combining
		    };
		    Util.CheckCohorts(expectedCohorts, cohorts);
		}
        //---------------------------------------------------------------------

        /// <summary>
        /// Computes the initial biomass for a cohort at a site.
        /// </summary>
        public static int InitialBiomass(ISpecies species,
                                         SiteCohorts cohorts,
                                         ActiveSite site)
        {
            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];

            double B_ACT = 0;  // Actual biomass - excluding "young" cohorts added in the same timestep

            // Copied from Library.BiomassCohorts.Cohorts.cs, but added restriction that age > 1 (required when running 1-year timestep)
            foreach (ISpeciesCohorts speciesCohorts in cohorts)
            {
                foreach (ICohort cohort in speciesCohorts)
                {
                    if ((cohort.Age >= PlugIn.SuccessionTimeStep) && (cohort.Age > 1))
                    {
                        B_ACT += cohort.Biomass;
                    }
                }
            }


            double maxBiomass = SpeciesData.B_MAX_Spp[species, ecoregion];

            double maxANPP = SpeciesData.ANPP_MAX_Spp[species, ecoregion];

            //  Initial biomass exponentially declines in response to
            //  competition.
            double initialBiomass = maxANPP * Math.Exp(-1.6 * B_ACT / EcoregionData.B_MAX[ecoregion]);


            // Initial biomass cannot be greater than maxANPP
            initialBiomass = Math.Min(maxANPP, initialBiomass);

            //  Initial biomass cannot be less than 2.  C. Dymond issue from August 2016
            initialBiomass = Math.Max(2.0, initialBiomass);

            return((int)initialBiomass);
        }
示例#31
0
        public SiteConditions GetFromKey(uint key)
        {
            SiteConditions s = null;

            if (initialSites.TryGetValue(key, out s) && siteoutput == null)
            {
                hydrology     = s.hydrology;
                establishment = s.Establishment;

                cohorts = new SiteCohorts();
                foreach (ISpeciesCohorts speciesCohorts in s.cohorts)
                {
                    foreach (Cohort cohort in speciesCohorts)
                    {
                        Cohort newcohort = new Cohort(cohort);
                        cohorts.AddNewCohort(newcohort, PlugIn.TStep);
                    }
                }
                forestfloor  = s.forestfloor;
                canopylaimax = s.CanopyLAImax;
            }
            return(s);
        }
        //---------------------------------------------------------------------
        public float CalculateEvaporation(SiteCohorts sitecohorts)
        {
            // permafrost
            float frostFreeSoilDepth = sitecohorts.Ecoregion.RootingDepth - FrozenDepth;
            float frostFreeProp      = Math.Min(1.0F, frostFreeSoilDepth / sitecohorts.Ecoregion.RootingDepth);

            float umolPAR = sitecohorts.SubcanopyPAR;

            if (PlugIn.PARunits == "W/m2")
            {
                umolPAR = (sitecohorts.SubcanopyPAR * 2.02f); // convertsolar radiation (W/m2) to PAR (umol/m2*s) [Reis and Ribeiro 2019 (Consants and Values)]
            }
            // mm/month
            PET = (float)Calculate_PotentialEvapotranspiration_umol(umolPAR, sitecohorts.Ecoregion.Variables.Tday, sitecohorts.Ecoregion.Variables.DaySpan);

            float pressurehead = pressureheadtable[sitecohorts.Ecoregion, (int)Math.Round(Water * 100)];

            // Evaporation begins to decline at 75% of field capacity (Robock et al. 1995)
            // Robock, A., Vinnikov, K. Y., Schlosser, C. A., Speranskaya, N. A., & Xue, Y. (1995). Use of midlatitude soil moisture and meteorological observations to validate soil moisture simulations with biosphere and bucket models. Journal of Climate, 8(1), 15-35.
            float evapCritWater   = sitecohorts.Ecoregion.FieldCap * 0.75f;
            float evapCritWaterPH = pressureheadtable[sitecohorts.Ecoregion, (int)Math.Round(evapCritWater * 100.0)];

            // Delivery potential is 1 if pressurehead < evapCritWater, and declines to 0 at wilting point (153 mH2O)
            DeliveryPotential = Cohort.ComputeFWater(-1, -1, evapCritWaterPH, 153, pressurehead);

            // mm/month
            float AET = Math.Min(DeliveryPotential * PET, Water * sitecohorts.Ecoregion.RootingDepth * frostFreeProp);

            sitecohorts.SetAet(AET, sitecohorts.Ecoregion.Variables.Month);

            // Evaporation cannot remove water below wilting point, evaporation cannot be negative
            // Transpiration is assumed to replace evaporation
            Evaporation = (float)Math.Max(0, Math.Min((Water - sitecohorts.Ecoregion.WiltPnt) * sitecohorts.Ecoregion.RootingDepth * frostFreeProp, Math.Max(0, AET - (double)sitecohorts.Transpiration)));

            return(Evaporation); //mm/month
        }
 //---------------------------------------------------------------------
 public ushort ComputeInitialBiomass(SiteCohorts siteCohorts,
                                     ActiveSite  site)
 {
     return initialBiomass;
 }
        //---------------------------------------------------------------------

        public ushort ComputeInitialBiomass(SiteCohorts siteCohorts,
                                            ActiveSite site)
        {
            return(initialBiomass);
        }
 //---------------------------------------------------------------------
 public static ISiteCohorts Clone(ISiteCohorts site_cohorts)
 {
     ISiteCohorts clone = new SiteCohorts();
     foreach (ISpeciesCohorts speciesCohorts in site_cohorts)
         foreach (ICohort cohort in speciesCohorts)
             clone.AddNewCohort(cohort.Species, cohort.Age, cohort.WoodBiomass, cohort.LeafBiomass);  //species.cohorts.Add(speciesCohorts.Clone());
     return clone;
 }
        //---------------------------------------------------------------------

        private void CohortsRemoved(object disturbance)
        {
            SiteCohorts  cohorts        = new SiteCohorts();
            const ushort initialBiomass = 40;

            mockCalculator.CountCalled = 0;
            mockCalculator.Change      = 1;

            int timeOfLastSucc = 0;

            for (int time = 1; time <= 50; time++)
            {
                //  Simulate the site being disturbed every 8 years which
                //  results in a new cohort being added.
                bool siteDisturbed = (time % 8 == 0);

                bool isSuccTimestep = (time % successionTimestep == 0);

                if (siteDisturbed || isSuccTimestep)
                {
                    Util.Grow(cohorts, (ushort)(time - timeOfLastSucc),
                              activeSite, isSuccTimestep);
                    timeOfLastSucc = time;
                }

                if (siteDisturbed)
                {
                    cohorts.AddNewCohort(poputrem, initialBiomass);
                }
            }

            //  Expected sequence of cohort changes:
            //
            //        Time  Grow_________
            //        Last         Cohorts               New
            //  Time  Succ  years  afterwards            Cohort
            //  ----  ----  -----  ---------------       ------
            //    8     0     8                           1(40)
            //   16     8     8    9(48)                  1(40)
            //   20    16     4    20(95*)                       * = 48+3 + 40+3 + 1
            //   24    20     4    24(99)                 1(40)
            //   32    24     8    32(107),9(48)          1(40)
            //   40    32     8    40(115),20(103*)       1(40)  * = 48+7 + 40+7 + 1
            //   48    40     8    48(123),28(111),9(48)  1(40)

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                48, 123,
                28, 111,
                9, 48,
                1, 40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            //  Remove cohorts whose ages are between 10 and 30
            expectedSender = cohorts[poputrem];
            deadCohorts.Clear();
            if (disturbance is IDisturbance)
            {
                cohorts.DamageBy((IDisturbance)disturbance);
            }
            else if (disturbance is AgeCohort.ICohortDisturbance)
            {
                ((AgeCohort.ISiteCohorts)cohorts).DamageBy((AgeCohort.ICohortDisturbance)disturbance);
            }

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                48, 123,
                1, 40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            CheckDeadCohorts(deadCohorts);
        }
示例#37
0
 public void Grow(DateTime date, ActiveSite site, Hydrology hydrology, ForestFloor forestfloor, SiteCohorts Cohorts, SiteOutput siteoutput)
 {
     SetCanopyLayers(Cohorts, MaxAge, MaxBiom);
     CalculateRadiationProfile(site, date);
     CalculatePhotosynthesis(date, site, hydrology, forestfloor, siteoutput);
 }
        public void Clone()
        {
            SiteCohorts  cohorts        = new SiteCohorts();
            const ushort initialBiomass = 55;

            cohorts.AddNewCohort(abiebals, initialBiomass);

            mockCalculator.CountCalled = 0;
            mockCalculator.Change      = 1;

            for (int time = successionTimestep; time <= 70; time += successionTimestep)
            {
                Util.Grow(cohorts, successionTimestep, activeSite, true);
                if (time % 20 == 0)
                {
                    cohorts.AddNewCohort(abiebals, initialBiomass);
                }
                if (time % 30 == 0)
                {
                    cohorts.AddNewCohort(betualle, initialBiomass);
                }
            }

            //  Expected cohort changes:
            //
            //  Time  Cohorts
            //  ----  -------
            //    0   abiebals 1(55)
            //   10   abiebals 10(65)
            //   20   abiebals 20(75) 1(55)
            //   30   abiebals 30(85) 10(65)
            //        betualle 1(55)
            //   40   abiebals 40(95) 20(75) 1(55)
            //        betualle 10(65)
            //   50   abiebals 50(105) 30(85) 10(65)
            //        betualle 20(75)
            //   60   abiebals 60(115) 40(95) 20(75) 1(55)
            //        betualle 30(85) 1(55)
            //   70   abiebals 70(125) 50(105) 30(85) 10(65)
            //        betualle 40(95) 10(65)
            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] {
                //  age  biomass
                70, 125,
                50, 105,
                30, 85,
                10, 65
            };
            expectedCohorts[betualle] = new ushort[] {
                //  age  biomass
                40, 95,
                10, 65
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            SiteCohorts clone = cohorts.Clone();

            Util.CheckCohorts(expectedCohorts, clone);

            //  Modify the original set of cohorts by growing them for 2 more
            //  succession timesteps.  Check that clone doesn't change.
            for (int time = 80; time <= 90; time += successionTimestep)
            {
                Util.Grow(cohorts, successionTimestep, activeSite, true);
            }
            Util.CheckCohorts(expectedCohorts, clone);

            expectedCohorts.Clear();
            expectedCohorts[abiebals] = new ushort[] {
                //  age  biomass
                90, 145,
                70, 125,
                50, 105,
                30, 85
            };
            expectedCohorts[betualle] = new ushort[] {
                //  age  biomass
                60, 115,
                30, 85
            };
            Util.CheckCohorts(expectedCohorts, cohorts);
        }
示例#39
0
        public override void Initialize()
        {
            PlugIn.ModelCore.UI.WriteLine("Initializing " + Names.ExtensionName + " version " + typeof(PlugIn).Assembly.GetName().Version);
            Cohort.DeathEvent += DeathEvent;

            Litter         = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.Biomass.Pool>();
            WoodyDebris    = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.Biomass.Pool>();
            sitecohorts    = PlugIn.ModelCore.Landscape.NewSiteVar <SiteCohorts>();
            FineFuels      = ModelCore.Landscape.NewSiteVar <Double>();
            PressureHead   = ModelCore.Landscape.NewSiteVar <float>();
            ExtremeMinTemp = ModelCore.Landscape.NewSiteVar <float>();
            Landis.Utilities.Directory.EnsureExists("output");

            Timestep = ((Parameter <int>)GetParameter(Names.Timestep)).Value;
            Parameter <string> CohortBinSizeParm = null;

            if (TryGetParameter(Names.CohortBinSize, out CohortBinSizeParm))
            {
                if (Int32.TryParse(CohortBinSizeParm.Value, out CohortBinSize))
                {
                    if (CohortBinSize < Timestep)
                    {
                        throw new System.Exception("CohortBinSize cannot be smaller than Timestep.");
                    }
                    else
                    {
                        PlugIn.ModelCore.UI.WriteLine("Succession timestep = " + Timestep + "; CohortBinSize = " + CohortBinSize + ".");
                    }
                }
                else
                {
                    throw new System.Exception("CohortBinSize is not an integer value.");
                }
            }
            else
            {
                CohortBinSize = Timestep;
            }


            FTimeStep = 1.0F / Timestep;

            //Latitude = ((Parameter<float>)PlugIn.GetParameter(Names.Latitude, 0, 90)).Value; // Now an ecoregion parameter

            ObservedClimate.Initialize();

            SpeciesPnET = new SpeciesPnET();

            EcoregionPnET.Initialize();
            Hydrology.Initialize();
            SiteCohorts.Initialize();

            // John McNabb: initialize climate library after EcoregionPnET has been initialized
            InitializeClimateLibrary();

            EstablishmentProbability.Initialize(Timestep);

            IMAX = ((Parameter <ushort>)GetParameter(Names.IMAX)).Value;
            //LeakageFrostDepth = ((Parameter<float>)GetParameter(Names.LeakageFrostDepth)).Value; //Now an ecoregion parameter
            //PrecipEvents = ((Parameter<float>)GetParameter(Names.PrecipEvents)).Value;// Now an ecoregion parameter


            // Initialize Reproduction routines:
            Reproduction.SufficientResources = SufficientResources;
            Reproduction.Establish           = Establish;
            Reproduction.AddNewCohort        = AddNewCohort;
            Reproduction.MaturePresent       = MaturePresent;
            Reproduction.PlantingEstablish   = PlantingEstablish;


            SeedingAlgorithms SeedAlgorithm = (SeedingAlgorithms)Enum.Parse(typeof(SeedingAlgorithms), parameters["SeedingAlgorithm"].Value);

            base.Initialize(ModelCore, SeedAlgorithm);


            StartDate = new DateTime(((Parameter <int>)GetParameter(Names.StartYear)).Value, 1, 15);

            PlugIn.ModelCore.UI.WriteLine("Spinning up biomass or reading from maps...");

            string             InitialCommunitiesTXTFile = GetParameter(Names.InitialCommunities).Value;
            string             InitialCommunitiesMapFile = GetParameter(Names.InitialCommunitiesMap).Value;
            Parameter <string> LitterMapFile;
            bool litterMapFile = TryGetParameter(Names.LitterMap, out LitterMapFile);
            Parameter <string> WoodyDebrisMapFile;
            bool woodyDebrisMapFile = TryGetParameter(Names.WoodyDebrisMap, out WoodyDebrisMapFile);

            //Console.ReadLine();
            InitializeSites(InitialCommunitiesTXTFile, InitialCommunitiesMapFile, ModelCore);
            if (litterMapFile)
            {
                MapReader.ReadLitterFromMap(LitterMapFile.Value);
            }
            if (woodyDebrisMapFile)
            {
                MapReader.ReadWoodyDebrisFromMap(WoodyDebrisMapFile.Value);
            }

            // Convert PnET cohorts to biomasscohorts
            ISiteVar <Landis.Library.BiomassCohorts.ISiteCohorts> biomassCohorts = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.BiomassCohorts.ISiteCohorts>();


            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                biomassCohorts[site] = sitecohorts[site];

                if (sitecohorts[site] != null && biomassCohorts[site] == null)
                {
                    throw new System.Exception("Cannot convert PnET SiteCohorts to biomass site cohorts");
                }
            }
            ModelCore.RegisterSiteVar(biomassCohorts, "Succession.BiomassCohorts");
            ModelCore.RegisterSiteVar(WoodyDebris, "Succession.WoodyDebris");
            ModelCore.RegisterSiteVar(Litter, "Succession.Litter");


            ISiteVar <Landis.Library.AgeOnlyCohorts.ISiteCohorts> AgeCohortSiteVar = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.AgeOnlyCohorts.ISiteCohorts>();
            ISiteVar <ISiteCohorts> PnETCohorts = PlugIn.ModelCore.Landscape.NewSiteVar <ISiteCohorts>();


            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                AgeCohortSiteVar[site] = sitecohorts[site];
                PnETCohorts[site]      = sitecohorts[site];
                FineFuels[site]        = Litter[site].Mass;
                IEcoregionPnET ecoregion = EcoregionPnET.GetPnETEcoregion(PlugIn.ModelCore.Ecoregion[site]);
                IHydrology     hydrology = new Hydrology(ecoregion.FieldCap);
                PressureHead[site] = hydrology.GetPressureHead(ecoregion);
                if (UsingClimateLibrary)
                {
                    ExtremeMinTemp[site] = ((float)Enumerable.Min(Climate.Future_MonthlyData[Climate.Future_MonthlyData.Keys.Min()][ecoregion.Index].MonthlyTemp) - (float)(3.0 * ecoregion.WinterSTD));
                }
                else
                {
                    ExtremeMinTemp[site] = 999;
                }
            }

            ModelCore.RegisterSiteVar(AgeCohortSiteVar, "Succession.AgeCohorts");
            ModelCore.RegisterSiteVar(PnETCohorts, "Succession.CohortsPnET");
            ModelCore.RegisterSiteVar(FineFuels, "Succession.FineFuels");
            ModelCore.RegisterSiteVar(PressureHead, "Succession.PressureHead");
            ModelCore.RegisterSiteVar(ExtremeMinTemp, "Succession.ExtremeMinTemp");
        }
        public void SetCanopyLayers(SiteCohorts Cohorts, int MaxAge, int MaxBiom)
        {
            int NewNrOfLayersMax = Canopy.GetNumberOfLayers(MaxAge);

            canopy = new List<CohortBiomass>[NewNrOfLayersMax+1];
            for (int canopylayer = 0; canopylayer < NewNrOfLayersMax+1; canopylayer++)
            {
                canopy[canopylayer] = new List<CohortBiomass>();
            }
            if (Cohorts == null) return;

            foreach (ISpeciesCohorts spc in Cohorts)
            {
                foreach (Cohort cohort in spc)
                {
                    // For initialization (all cohorts end up in one layer the first call regardless of biomass).
                    // This is not pretty but saves computation time.
                    if (MaxBiom < cohort.Biomass) MaxBiom = cohort.Biomass;

                    // The max is not to allow a lower canopy layer than previously.
                    float ratio = (float)(cohort.Biomass) / MaxBiom;

                    int actuallayer = (int)(ratio * NewNrOfLayersMax) - 1;

                    if (MaxBiom > 0)
                    {
                        // only reset CanopyLayer if NumberOfLayersMax changed
                        if (NewNrOfLayersMax != NumberOfLayersMax)
                        {
                            cohort.CanopyLayer = Math.Min(NewNrOfLayersMax, Math.Max(cohort.CanopyLayer, actuallayer));
                        }
                    }

                    if (cohort.CanopyLayer > canopy.Length)
                    {
                        throw new System.Exception("cannot implement canopylayer = " + cohort.CanopyLayer + " number of canopy layers is " + canopy.Length + " MaxAge = " + MaxAge);
                    }

                    canopy[cohort.CanopyLayer].Add(new CohortBiomass(cohort));
                }
            }
            NumberOfLayersMax = NewNrOfLayersMax;
        }
 private int GetMaxAge(SiteCohorts Cohorts)
 {
     int maxage = int.MinValue;
     foreach (ISpeciesCohorts spc in Cohorts)
     {
         foreach (ICohort cohort in spc)
         {
             if (cohort.Age > maxage) maxage = cohort.Age;
         }
     }
     return maxage;
 }
 public void Grow(DateTime date, ActiveSite site, Hydrology hydrology, ForestFloor forestfloor, SiteCohorts Cohorts, SiteOutput siteoutput)
 {
     SetCanopyLayers(Cohorts, MaxAge, MaxBiom);
     CalculateRadiationProfile(site, date);
     CalculatePhotosynthesis(date, site, hydrology, forestfloor, siteoutput);
 }
        //---------------------------------------------------------------------

        private void CohortsRemoved(object disturbance)
        {
            SiteCohorts cohorts = new SiteCohorts();
            const ushort initialBiomass = 40;

            mockCalculator.CountCalled = 0;
            mockCalculator.Change = 1;

            int timeOfLastSucc = 0;
            for (int time = 1; time <= 50; time++) {
                //  Simulate the site being disturbed every 8 years which
                //  results in a new cohort being added.
                bool siteDisturbed = (time % 8 == 0);

                bool isSuccTimestep = (time % successionTimestep == 0);

                if (siteDisturbed || isSuccTimestep) {
                    Util.Grow(cohorts, (ushort) (time - timeOfLastSucc),
                              activeSite, isSuccTimestep);
                    timeOfLastSucc = time;
                }

                if (siteDisturbed)
                    cohorts.AddNewCohort(poputrem, initialBiomass);
            }

            //  Expected sequence of cohort changes:
            //
            //        Time  Grow_________
            //        Last         Cohorts               New
            //  Time  Succ  years  afterwards            Cohort
            //  ----  ----  -----  ---------------       ------
            //    8     0     8                           1(40)
            //   16     8     8    9(48)                  1(40)
            //   20    16     4    20(95*)                       * = 48+3 + 40+3 + 1
            //   24    20     4    24(99)                 1(40)
            //   32    24     8    32(107),9(48)          1(40)
            //   40    32     8    40(115),20(103*)       1(40)  * = 48+7 + 40+7 + 1
            //   48    40     8    48(123),28(111),9(48)  1(40)

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                    48,    123,
                    28,    111,
                     9,     48,
                     1,     40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            //  Remove cohorts whose ages are between 10 and 30
            expectedSender = cohorts[poputrem];
            deadCohorts.Clear();
            if (disturbance is IDisturbance)
                cohorts.DamageBy((IDisturbance) disturbance);
            else if (disturbance is AgeCohort.IDisturbance)
                ((AgeCohort.ISiteCohorts) cohorts).DamageBy((AgeCohort.IDisturbance) disturbance);

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                    48,    123,
                     1,     40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);
            
            CheckDeadCohorts(deadCohorts);
        }
        public SiteConditions GetFromKey(uint key)
        {
            SiteConditions s=null;
            if (initialSites.TryGetValue(key, out s) && siteoutput == null)
            {
                hydrology = s.hydrology;
                establishment = s.Establishment;

                cohorts = new SiteCohorts();
                foreach (ISpeciesCohorts speciesCohorts in s.cohorts)
                {
                    foreach (Cohort cohort in speciesCohorts)
                    {
                        Cohort newcohort = new Cohort(cohort);
                        cohorts.AddNewCohort(newcohort, PlugIn.TStep);
                    }
                }
                forestfloor = s.forestfloor;
                canopylaimax = s.CanopyLAImax;
            }
            return s;
        }
        public void CohortsRemoved()
        {
            SiteCohorts  cohorts        = new SiteCohorts();
            const ushort initialBiomass = 40;

            mockCalculator.CountCalled = 0;
            mockCalculator.Change      = 1;

            int timeOfLastSucc = 0;

            for (int time = 1; time <= 50; time++)
            {
                //  Simulate the site being disturbed every 8 years which
                //  results in a new cohort being added.
                bool siteDisturbed = (time % 8 == 0);

                bool isSuccTimestep = (time % successionTimestep == 0);

                if (siteDisturbed || isSuccTimestep)
                {
                    Util.Grow(cohorts, (ushort)(time - timeOfLastSucc),
                              activeSite, isSuccTimestep);
                    timeOfLastSucc = time;
                }

                if (siteDisturbed)
                {
                    cohorts.AddNewCohort(poputrem, initialBiomass);
                }
            }

            //  Expected sequence of cohort changes:
            //
            //        Time  Grow_________
            //        Last         Cohorts               New
            //  Time  Succ  years  afterwards            Cohort
            //  ----  ----  -----  ---------------       ------
            //    8     0     8                           1(40)
            //   16     8     8    9(48)                  1(40)
            //   20    16     4    20(95*)                       * = 48+3 + 40+3 + 1
            //   24    20     4    24(99)                 1(40)
            //   32    24     8    32(107),9(48)          1(40)
            //   40    32     8    40(115),20(103*)       1(40)  * = 48+7 + 40+7 + 1
            //   48    40     8    48(123),28(111),9(48)  1(40)

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                48, 123,
                28, 111,
                9, 48,
                1, 40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            //  Remove cohorts whose ages are between 10 and 30
            expectedSite = null;
            deadCohorts.Clear();
            cohorts.DamageBy(new RemoveAgeBetween5And30(expectedSite));

            expectedCohorts.Clear();
            expectedCohorts[poputrem] = new ushort[] {
                //  age  biomass
                48, 123,
                1, 40
            };
            Util.CheckCohorts(expectedCohorts, cohorts);

            Assert.AreEqual(2, deadCohorts.Count);
            ushort[] cohortData = new ushort[] {
                //  age  biomass (in young to old order because Remove goes
                //                from back to front)
                9, 48,
                28, 111
            };
            for (int i = 0; i < deadCohorts.Count; i++)
            {
                ICohort deadCohort = deadCohorts[i];
                Assert.AreEqual(poputrem, deadCohort.Species);
                Assert.AreEqual(cohortData[i * 2], deadCohort.Age);
                Assert.AreEqual(cohortData[i * 2 + 1], deadCohort.Biomass);
            }
        }
        public float CalculateEvaporation(SiteCohorts sitecohorts )
        {
            // this.Ecoregion.Variables.Month, Ecoregion, this.subcanopypar, Transpiration, this.Ecoregion.Variables.Tday, ref water,this.SetAet
            PET = (float)Calculate_PotentialEvapotranspiration(sitecohorts.SubcanopyPAR, sitecohorts.Ecoregion.Variables.Tday);

            float pressurehead = pressureheadtable[sitecohorts.Ecoregion, (int)Water];

            // Evaporation begins to decline at 75% of field capacity (Robock et al. 1995)
            // Robock, A., Vinnikov, K. Y., Schlosser, C. A., Speranskaya, N. A., & Xue, Y. (1995). Use of midlatitude soil moisture and meteorological observations to validate soil moisture simulations with biosphere and bucket models. Journal of Climate, 8(1), 15-35.
            float evapCritWater = sitecohorts.Ecoregion.FieldCap * 0.75f;

            DeliveryPotential = Cohort.ComputeFWater(0, evapCritWater, 153, pressurehead);

            // Per month
            sitecohorts.SetAet(DeliveryPotential * PET, sitecohorts.Ecoregion.Variables.Month);

            float wiltPoint = sitecohorts.Ecoregion.WiltPnt;

            // Evaporation cannot remove water below wilting point, evaporation cannot be negative
            // Transpiration is assumed to replace evaporation
            Evaporation = (float)Math.Max(0,Math.Min(Water - wiltPoint, Math.Max(0, DeliveryPotential * PET - (double)sitecohorts.Transpiration)));

            return Evaporation;
        }
        public void SingleCohort_ZeroBiomass()
        {
            SiteCohorts cohorts = new SiteCohorts();
            const ushort initialBiomass = 100;
            cohorts.AddNewCohort(poputrem, initialBiomass);

            mockCalculator.CountCalled = 0;
            mockCalculator.Change = -2;

            expectedSender = cohorts[poputrem];
            expectedDistType = null;  // death during growth phase
            expectedSite = activeSite;
            deadCohorts.Clear();

            for (int time = 1; time <= 60; time++) {
                if (time % successionTimestep == 0)
                    Util.Grow(cohorts, successionTimestep, activeSite, true);
            }

            expectedCohorts.Clear();
            Util.CheckCohorts(expectedCohorts, cohorts);

            Assert.AreEqual(1, deadCohorts.Count);
            ICohort deadCohort = deadCohorts[0];
            Assert.AreEqual(poputrem, deadCohort.Species);
            Assert.AreEqual(initialBiomass / -mockCalculator.Change, deadCohort.Age);
            Assert.AreEqual(0, deadCohort.Biomass);
        }
 // Makes sure that litters are allocated to the appropriate site
 public static void SetSiteAccessFunctions(SiteCohorts sitecohorts)
 {
     Cohort.addlitter = sitecohorts.AddLitter;
      Cohort.addwoodydebris = sitecohorts.AddWoodyDebris;
      Cohort.ecoregion = sitecohorts.Ecoregion;
 }
        //---------------------------------------------------------------------
        /// <summary>
        /// Computes the initial biomass for a cohort at a site.
        /// </summary>
        public static int InitialBiomass(ISpecies species,
                                            SiteCohorts siteCohorts,
                                            ActiveSite site)
        {
            IEcoregion ecoregion = PlugIn.ModelCore.Ecoregion[site];
            //double B_ACT = ActualSiteBiomass(siteCohorts, site, out ecoregion);

            double B_ACT = (double)Cohorts.ComputeNonYoungBiomass(siteCohorts);

            double maxBiomass = SpeciesData.B_MAX_Spp[species][ecoregion];

            double maxANPP = SpeciesData.ANPP_MAX_Spp[species][ecoregion];

            //  Initial biomass exponentially declines in response to
            //  competition.
            //double initialBiomass = 0.025 * maxBiomass * Math.Exp(-1.6 * B_ACT / EcoregionData.B_MAX[ecoregion]);
            double initialBiomass = maxANPP * Math.Exp(-1.6 * B_ACT / EcoregionData.B_MAX[ecoregion]);

            // Initial biomass cannot be greater than maxANPP
            initialBiomass = Math.Min(maxANPP, initialBiomass);

            //  Initial biomass cannot be less than 1.
            initialBiomass = Math.Max(1.0, initialBiomass);

            return (int)initialBiomass;
        }
示例#50
0
        //---------------------------------------------------------------------
        public override void Initialize()
        {
            PlugIn.ModelCore.UI.WriteLine("Initializing " + Names.ExtensionName + " version " + typeof(PlugIn).Assembly.GetName().Version);
            Cohort.DeathEvent += DeathEvent;
            Globals.InitializeCore(ModelCore, ((Parameter <ushort>)Names.GetParameter(Names.IMAX)).Value);
            EcoregionData.Initialize();
            SiteVars.Initialize();

            Landis.Utilities.Directory.EnsureExists("output");

            Timestep = ((Parameter <int>)Names.GetParameter(Names.Timestep)).Value;
            Parameter <string> CohortBinSizeParm = null;

            if (Names.TryGetParameter(Names.CohortBinSize, out CohortBinSizeParm))
            {
                if (Int32.TryParse(CohortBinSizeParm.Value, out CohortBinSize))
                {
                    if (CohortBinSize < Timestep)
                    {
                        throw new System.Exception("CohortBinSize cannot be smaller than Timestep.");
                    }
                    else
                    {
                        PlugIn.ModelCore.UI.WriteLine("Succession timestep = " + Timestep + "; CohortBinSize = " + CohortBinSize + ".");
                    }
                }
                else
                {
                    throw new System.Exception("CohortBinSize is not an integer value.");
                }
            }
            else
            {
                CohortBinSize = Timestep;
            }

            string Parallel = ((Parameter <string>)Names.GetParameter(Names.Parallel)).Value;

            if (Parallel == "false")
            {
                ParallelThreads = 1;
                PlugIn.ModelCore.UI.WriteLine("  MaxParallelThreads = " + ParallelThreads.ToString() + ".");
            }
            else if (Parallel == "true")
            {
                ParallelThreads = -1;
                PlugIn.ModelCore.UI.WriteLine("  MaxParallelThreads determined by system.");
            }
            else
            {
                if (Int32.TryParse(Parallel, out ParallelThreads))
                {
                    if (ParallelThreads < 1)
                    {
                        throw new System.Exception("Parallel cannot be < 1.");
                    }
                    else
                    {
                        PlugIn.ModelCore.UI.WriteLine("  MaxParallelThreads = " + ParallelThreads.ToString() + ".");
                    }
                }
                else
                {
                    throw new System.Exception("Parallel must be 'true', 'false' or an integer >= 1.");
                }
            }
            this.ThreadCount = ParallelThreads;

            FTimeStep = 1.0F / Timestep;

            //Latitude = ((Parameter<float>)PlugIn.GetParameter(Names.Latitude, 0, 90)).Value; // Now an ecoregion parameter

            ObservedClimate.Initialize();
            SpeciesPnET = new SpeciesPnET();
            Landis.Library.PnETCohorts.SpeciesParameters.LoadParameters(SpeciesPnET);

            Hydrology.Initialize();
            SiteCohorts.Initialize();
            string PARunits = ((Parameter <string>)Names.GetParameter(Names.PARunits)).Value;

            if (PARunits != "umol" && PARunits != "W/m2")
            {
                throw new System.Exception("PARunits are not 'umol' or 'W/m2'.");
            }
            InitializeClimateLibrary(); // John McNabb: initialize climate library after EcoregionPnET has been initialized
            //EstablishmentProbability.Initialize(Timestep);  // Not used

            // Initialize Reproduction routines:
            Reproduction.SufficientResources = SufficientResources;
            Reproduction.Establish           = Establish;
            Reproduction.AddNewCohort        = AddNewCohort;
            Reproduction.MaturePresent       = MaturePresent;
            Reproduction.PlantingEstablish   = PlantingEstablish;
            SeedingAlgorithms SeedAlgorithm = (SeedingAlgorithms)Enum.Parse(typeof(SeedingAlgorithms), Names.parameters["SeedingAlgorithm"].Value);

            base.Initialize(ModelCore, SeedAlgorithm);

            StartDate = new DateTime(((Parameter <int>)Names.GetParameter(Names.StartYear)).Value, 1, 15);

            PlugIn.ModelCore.UI.WriteLine("Spinning up biomass or reading from maps...");

            string InitialCommunitiesTXTFile = Names.GetParameter(Names.InitialCommunities).Value;
            string InitialCommunitiesMapFile = Names.GetParameter(Names.InitialCommunitiesMap).Value;

            InitialCommunitiesSpinup = Names.GetParameter(Names.InitialCommunitiesSpinup).Value;
            Parameter <string> LitterMapFile;
            bool litterMapFile = Names.TryGetParameter(Names.LitterMap, out LitterMapFile);
            Parameter <string> WoodyDebrisMapFile;
            bool woodyDebrisMapFile = Names.TryGetParameter(Names.WoodyDebrisMap, out WoodyDebrisMapFile);

            InitializeSites(InitialCommunitiesTXTFile, InitialCommunitiesMapFile, ModelCore);
            if (litterMapFile)
            {
                MapReader.ReadLitterFromMap(LitterMapFile.Value);
            }
            if (woodyDebrisMapFile)
            {
                MapReader.ReadWoodyDebrisFromMap(WoodyDebrisMapFile.Value);
            }

            // Convert PnET cohorts to biomasscohorts
            ISiteVar <Landis.Library.BiomassCohorts.ISiteCohorts> biomassCohorts = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.BiomassCohorts.ISiteCohorts>();

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                biomassCohorts[site] = SiteVars.SiteCohorts[site];

                if (SiteVars.SiteCohorts[site] != null && biomassCohorts[site] == null)
                {
                    throw new System.Exception("Cannot convert PnET SiteCohorts to biomass site cohorts");
                }
            }
            ModelCore.RegisterSiteVar(biomassCohorts, "Succession.BiomassCohorts");

            ISiteVar <Landis.Library.AgeOnlyCohorts.ISiteCohorts> AgeCohortSiteVar = PlugIn.ModelCore.Landscape.NewSiteVar <Landis.Library.AgeOnlyCohorts.ISiteCohorts>();
            ISiteVar <ISiteCohorts> PnETCohorts = PlugIn.ModelCore.Landscape.NewSiteVar <ISiteCohorts>();

            foreach (ActiveSite site in PlugIn.ModelCore.Landscape)
            {
                AgeCohortSiteVar[site]   = SiteVars.SiteCohorts[site];
                PnETCohorts[site]        = SiteVars.SiteCohorts[site];
                SiteVars.FineFuels[site] = SiteVars.Litter[site].Mass;
                IEcoregionPnET ecoregion = EcoregionData.GetPnETEcoregion(PlugIn.ModelCore.Ecoregion[site]);
                IHydrology     hydrology = new Hydrology(ecoregion.FieldCap);
                SiteVars.PressureHead[site] = hydrology.GetPressureHead(ecoregion);
                if (UsingClimateLibrary)
                {
                    SiteVars.ExtremeMinTemp[site] = ((float)Enumerable.Min(Climate.Future_MonthlyData[Climate.Future_MonthlyData.Keys.Min()][ecoregion.Index].MonthlyTemp) - (float)(3.0 * ecoregion.WinterSTD));
                }
                else
                {
                    SiteVars.ExtremeMinTemp[site] = 999;
                }
            }

            ModelCore.RegisterSiteVar(AgeCohortSiteVar, "Succession.AgeCohorts");
            ModelCore.RegisterSiteVar(PnETCohorts, "Succession.CohortsPnET");
        }