コード例 #1
0
ファイル: OrganonVariantRap.cs プロジェクト: OSU-MARS/SEEM
        public override float GetGrowthEffectiveAge(OrganonConfiguration configuration, OrganonStand stand, Trees trees, int treeIndex, out float potentialHeightGrowth)
        {
            float growthEffectiveAge;

            if (trees.Species == FiaCode.AlnusRubra)
            {
                // GROWTH EFFECTIVE AGE AND POTENTIAL HEIGHT GROWTH FROM WEISKITTEL, HANN, HIBBS, LAM, AND BLUHM (2009) RED ALDER TOP HEIGHT GROWTH
                float siteIndexFromGround = stand.SiteIndex + 4.5F;
                RedAlder.WHHLB_HG(siteIndexFromGround, configuration.PDEN, trees.Height[treeIndex], 1.0F, out growthEffectiveAge, out potentialHeightGrowth);
            }
            else if (trees.Species == FiaCode.TsugaHeterophylla)
            {
                // POTENTIAL HEIGHT GROWTH FROM FLEWELLING'S WESTERN HEMLOCK DOMINANT HEIGHT GROWTH
                // BUGBUG: why isn't redcedar also on this code path?
                float siteIndexFromGround             = OrganonVariantNwo.ToHemlockSiteIndexStatic(stand.HemlockSiteIndex); // stand.HemlockSiteIndex is interpreted as PSME site index
                WesternHemlock.SiteConstants tsheSite = new WesternHemlock.SiteConstants(siteIndexFromGround);
                growthEffectiveAge = WesternHemlock.GetFlewellingGrowthEffectiveAge(tsheSite, this.TimeStepInYears, trees.Height[treeIndex], out potentialHeightGrowth);
            }
            else
            {
                // POTENTIAL HEIGHT GROWTH FROM BRUCE'S (1981) DOMINANT HEIGHT GROWTH FOR DOUGLAS-FIR AND GRAND FIR
                DouglasFir.SiteConstants psmeSite = new DouglasFir.SiteConstants(stand.HemlockSiteIndex); // stand.HemlockSiteIndex is interpreted as PSME site index
                growthEffectiveAge = DouglasFir.GetBrucePsmeAbgrGrowthEffectiveAge(psmeSite, this.TimeStepInYears, trees.Height[treeIndex], out potentialHeightGrowth);
            }
            return(growthEffectiveAge);
        }
コード例 #2
0
        public void WesternHemlockApi()
        {
            this.TestContext !.WriteLine("siteIndex, age, topHeight");
            for (float siteIndexInMeters = 10.0F; siteIndexInMeters < 60.1F; siteIndexInMeters += 10.0F)
            {
                WesternHemlock.SiteConstants tsheSite = new WesternHemlock.SiteConstants(Constant.FeetPerMeter * siteIndexInMeters);
                float previousTopHeight = -1.0F;
                for (float ageInYears = 0.0F; ageInYears < 100.1F; ++ageInYears)
                {
                    WesternHemlock.SITECV_F(tsheSite, ageInYears, out float topHeightInMeters);
                    this.TestContext.WriteLine("{0},{1},{2}", siteIndexInMeters, ageInYears, topHeightInMeters);

                    Assert.IsTrue(topHeightInMeters >= 0.0F);
                    // could add check that SI at age 50 is close to specified value
                    Assert.IsTrue(topHeightInMeters > previousTopHeight);
                    Assert.IsTrue(topHeightInMeters < 100.0F);

                    previousTopHeight = topHeightInMeters;
                }
            }
        }
コード例 #3
0
        public void HeightGrowthApi()
        {
            foreach (OrganonVariant variant in TestConstant.Variants)
            {
                OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant);
                Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();
                TestStand stand = OrganonTest.CreateDefaultStand(configuration);

                float[] crownCompetitionByHeight      = OrganonStandDensity.GetCrownCompetitionByHeight(variant, stand);
                DouglasFir.SiteConstants     psmeSite = new DouglasFir.SiteConstants(stand.SiteIndex);
                WesternHemlock.SiteConstants tsheSite = new WesternHemlock.SiteConstants(stand.HemlockSiteIndex);

                foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                {
                    variant.GetHeightPredictionCoefficients(treesOfSpecies.Species, out float B0, out float B1, out float B2);
                    for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex)
                    {
                        // predicted heights
                        float dbhInInches           = treesOfSpecies.Dbh[treeIndex];
                        float heightInFeet          = treesOfSpecies.Height[treeIndex];
                        float predictedHeightInFeet = 4.5F + MathV.Exp(B0 + B1 * MathV.Pow(dbhInInches, B2));
                        Assert.IsTrue(predictedHeightInFeet >= 0.0F);
                        // TODO: make upper limit of height species specific
                        Assert.IsTrue(predictedHeightInFeet < TestConstant.Maximum.HeightInFeet);

                        // growth effective age and potential height growth
                        bool  verifyAgeAndHeight        = false;
                        float growthEffectiveAgeInYears = -1.0F;
                        float potentialHeightGrowth     = -1.0F;
                        if ((variant.TreeModel == TreeModel.OrganonNwo) || (variant.TreeModel == TreeModel.OrganonSmc))
                        {
                            if (treesOfSpecies.Species == FiaCode.TsugaHeterophylla)
                            {
                                growthEffectiveAgeInYears = WesternHemlock.GetFlewellingGrowthEffectiveAge(tsheSite, variant.TimeStepInYears, heightInFeet, out potentialHeightGrowth);
                            }
                            else
                            {
                                growthEffectiveAgeInYears = DouglasFir.GetBrucePsmeAbgrGrowthEffectiveAge(psmeSite, variant.TimeStepInYears, heightInFeet, out potentialHeightGrowth);
                            }
                            verifyAgeAndHeight = true;
                        }
                        else if (variant.TreeModel == TreeModel.OrganonSwo)
                        {
                            if ((treesOfSpecies.Species == FiaCode.PinusPonderosa) || (treesOfSpecies.Species == FiaCode.PseudotsugaMenziesii))
                            {
                                DouglasFir.GetDouglasFirPonderosaHeightGrowth(treesOfSpecies.Species == FiaCode.PseudotsugaMenziesii, stand.SiteIndex, heightInFeet, out growthEffectiveAgeInYears, out potentialHeightGrowth);
                                verifyAgeAndHeight = true;
                            }
                        }
                        if (verifyAgeAndHeight)
                        {
                            Assert.IsTrue(growthEffectiveAgeInYears >= -2.0F);
                            Assert.IsTrue(growthEffectiveAgeInYears <= 500.0F);
                            Assert.IsTrue(potentialHeightGrowth >= 0.0F);
                            Assert.IsTrue(potentialHeightGrowth < 20.0F);
                        }
                    }
                }

                for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep)
                {
                    foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                    {
                        if (variant.IsBigSixSpecies(treesOfSpecies.Species))
                        {
                            // TODO: why no height calibration in Organon API?
                            OrganonGrowth.GrowHeightBigSixSpecies(configuration, simulationStep, stand, treesOfSpecies, 1.0F, crownCompetitionByHeight, out _);
                        }
                        else
                        {
                            OrganonGrowth.GrowHeightMinorSpecies(configuration, stand, treesOfSpecies, calibrationBySpecies[treesOfSpecies.Species].Height);
                        }
                        stand.SetSdiMax(configuration);

                        for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex)
                        {
                            float heightInFeet = treesOfSpecies.Height[treeIndex];
                            // TODO: make upper limit of height species specific
                            Assert.IsTrue(heightInFeet < TestConstant.Maximum.HeightInFeet);
                        }
                    }

                    // since diameter growth is zero in this test any tree which is above its anticipated height for its current diameter
                    // should have zero growth
                    // This is expected behavior the height growth functions and, potentially, height growth limiting.
                    OrganonTest.Verify(ExpectedTreeChanges.HeightGrowthOrNoChange, stand, variant);
                    OrganonTest.Verify(calibrationBySpecies);
                }
            }
        }