Esempio n. 1
0
        public void OrganonStandGrowthApi()
        {
            TestStand.WriteTreeHeader(this.TestContext !);
            foreach (OrganonVariant variant in TestConstant.Variants)
            {
                OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant);

                // check crown competition API
                TestStand stand = OrganonTest.CreateDefaultStand(configuration);
                float     crownCompetitionFactor = OrganonStandDensity.GetCrownCompetitionByHeight(variant, stand)[0];
                Assert.IsTrue(crownCompetitionFactor >= 0.0F);
                Assert.IsTrue(crownCompetitionFactor <= TestConstant.Maximum.CrownCompetitionFactor);
                OrganonTest.Verify(ExpectedTreeChanges.NoDiameterOrHeightGrowth | ExpectedTreeChanges.NoDiameterOrHeightGrowth, stand, variant);

                // recalculate heights and crown ratios for all trees
                Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();
                foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                {
                    OrganonGrowth.SetIngrowthHeightAndCrownRatio(variant, stand, treesOfSpecies, treesOfSpecies.Count, calibrationBySpecies);
                }
                OrganonTest.Verify(ExpectedTreeChanges.NoDiameterOrHeightGrowth | ExpectedTreeChanges.NoDiameterOrHeightGrowth, stand, variant);

                // run Organon growth simulation
                stand = OrganonTest.CreateDefaultStand(configuration);
                if (configuration.IsEvenAge)
                {
                    // stand error if less than one year to grow to breast height
                    stand.AgeInYears = stand.BreastHeightAgeInYears + 2;
                }
                stand.SetQuantiles();
                stand.WriteTreesAsCsv(this.TestContext !, variant, 0, false);

                TestStand        initialStand = new TestStand(stand);
                TreeLifeAndDeath treeGrowth   = new TreeLifeAndDeath();
                for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep)
                {
                    OrganonGrowth.Grow(simulationStep, configuration, stand, calibrationBySpecies);
                    treeGrowth.AccumulateGrowthAndMortality(stand);
                    OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth | ExpectedTreeChanges.HeightGrowth, OrganonWarnings.LessThan50TreeRecords, stand, variant);

                    stand.WriteTreesAsCsv(this.TestContext !, variant, variant.GetEndYear(simulationStep), false);
                }

                OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth | ExpectedTreeChanges.HeightGrowth, treeGrowth, initialStand, stand);
                OrganonTest.Verify(calibrationBySpecies);
            }
        }
Esempio n. 2
0
        public void DiameterGrowthApi()
        {
            foreach (OrganonVariant variant in TestConstant.Variants)
            {
                OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant);
                TestStand            stand         = OrganonTest.CreateDefaultStand(configuration);
                Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();

                Dictionary <FiaCode, float[]> previousTreeDiametersBySpecies = new Dictionary <FiaCode, float[]>();
                foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                {
                    previousTreeDiametersBySpecies.Add(treesOfSpecies.Species, new float[treesOfSpecies.Capacity]);
                }

                for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep)
                {
                    OrganonStandDensity treeCompetition = new OrganonStandDensity(stand, variant);
                    foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                    {
                        float[] previousTreeDiameters = previousTreeDiametersBySpecies[treesOfSpecies.Species];
                        OrganonGrowth.GrowDiameter(configuration, simulationStep, stand, treesOfSpecies, treeCompetition, calibrationBySpecies[treesOfSpecies.Species].Diameter);
                        stand.SetSdiMax(configuration);
                        for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex)
                        {
                            float dbhInInches         = treesOfSpecies.Dbh[treeIndex];
                            float previousDbhInInches = previousTreeDiameters[treeIndex];
                            Assert.IsTrue(dbhInInches >= previousDbhInInches);
                            Assert.IsTrue(dbhInInches <= TestConstant.Maximum.DiameterInInches);
                        }
                    }

                    OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth, stand, variant);
                    OrganonTest.Verify(calibrationBySpecies);
                }

                OrganonStandDensity densityForLookup = new OrganonStandDensity(stand, variant);
                for (float dbhInInches = 0.5F; dbhInInches <= 101.0F; ++dbhInInches)
                {
                    float basalAreaLarger = densityForLookup.GetBasalAreaLarger(dbhInInches);
                    Assert.IsTrue(basalAreaLarger >= 0.0F);
                    Assert.IsTrue(basalAreaLarger <= densityForLookup.BasalAreaPerAcre);
                    float crownCompetitionLarger = densityForLookup.GetCrownCompetitionFactorLarger(dbhInInches);
                    Assert.IsTrue(crownCompetitionLarger >= 0.0F);
                    Assert.IsTrue(crownCompetitionLarger <= densityForLookup.CrownCompetitionFactor);
                }
            }
        }
Esempio n. 3
0
        protected static void GrowPspStand(PspStand huffmanPeak, TestStand stand, OrganonVariant variant, int startYear, int endYear, string baseFileName)
        {
            OrganonConfiguration configuration   = OrganonTest.CreateOrganonConfiguration(variant);
            TestStand            initialTreeData = new TestStand(stand);
            TreeLifeAndDeath     treeGrowth      = new TreeLifeAndDeath();

            Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();

            if (configuration.IsEvenAge)
            {
                // stand error if less than one year to grow to breast height
                stand.AgeInYears = stand.BreastHeightAgeInYears + 2;
            }

            TestStandDensity density = new TestStandDensity(stand, variant);

            using StreamWriter densityWriter = density.WriteToCsv(baseFileName + " density.csv", variant, startYear);
            TreeQuantiles quantiles = new TreeQuantiles(stand);

            using StreamWriter quantileWriter   = quantiles.WriteToCsv(baseFileName + " quantiles.csv", variant, startYear);
            using StreamWriter treeGrowthWriter = stand.WriteTreesToCsv(baseFileName + " tree growth.csv", variant, startYear);
            for (int simulationStep = 0, year = startYear + variant.TimeStepInYears; year <= endYear; year += variant.TimeStepInYears, ++simulationStep)
            {
                OrganonGrowth.Grow(simulationStep, configuration, stand, calibrationBySpecies);
                treeGrowth.AccumulateGrowthAndMortality(stand);
                huffmanPeak.AddIngrowth(year, stand, density);
                OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowthOrNoChange | ExpectedTreeChanges.HeightGrowthOrNoChange, stand, variant);

                density = new TestStandDensity(stand, variant);
                density.WriteToCsv(densityWriter, variant, year);
                quantiles = new TreeQuantiles(stand);
                quantiles.WriteToCsv(quantileWriter, variant, year);
                stand.WriteTreesToCsv(treeGrowthWriter, variant, year);
            }

            OrganonTest.Verify(ExpectedTreeChanges.ExpansionFactorConservedOrIncreased | ExpectedTreeChanges.DiameterGrowthOrNoChange | ExpectedTreeChanges.HeightGrowthOrNoChange, treeGrowth, initialTreeData, stand);
            OrganonTest.Verify(calibrationBySpecies);
        }
Esempio n. 4
0
        public void GrowApi()
        {
            foreach (OrganonVariant variant in TestConstant.Variants)
            {
                OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant);
                TestStand            stand         = OrganonTest.CreateDefaultStand(configuration);

                Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();
                OrganonStandDensity densityStartOfStep = new OrganonStandDensity(stand, variant);
                for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep)
                {
                    float[] crownCompetitionByHeight = OrganonStandDensity.GetCrownCompetitionByHeight(variant, stand);
                    OrganonGrowth.Grow(simulationStep, configuration, stand, densityStartOfStep, calibrationBySpecies, ref crownCompetitionByHeight,
                                       out OrganonStandDensity densityEndOfStep, out int _);
                    stand.SetSdiMax(configuration);

                    OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth | ExpectedTreeChanges.HeightGrowth, stand, variant);
                    OrganonTest.Verify(calibrationBySpecies);

                    densityStartOfStep = densityEndOfStep;
                }
            }
        }
Esempio n. 5
0
        public void CrownGrowthApi()
        {
            foreach (OrganonVariant variant in TestConstant.Variants)
            {
                OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant);
                TestStand            stand         = OrganonTest.CreateDefaultStand(configuration);

                Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration();
                for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep)
                {
                    OrganonStandDensity densityStartOfStep = new OrganonStandDensity(stand, variant);
                    Assert.IsTrue(densityStartOfStep.BasalAreaPerAcre > 0.0F);
                    Assert.IsTrue(densityStartOfStep.CrownCompetitionFactor > 0.0F);
                    Assert.IsTrue(densityStartOfStep.TreesPerAcre > 0.0F);

                    float[] crownCompetitionByHeight = OrganonStandDensity.GetCrownCompetitionByHeight(variant, stand);
                    OrganonTest.Verify(crownCompetitionByHeight, variant);

                    foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
                    {
                        variant.AddCrownCompetitionByHeight(treesOfSpecies, crownCompetitionByHeight);
                        OrganonTest.Verify(crownCompetitionByHeight, variant);
                    }

                    OrganonStandDensity densityEndOfStep = new OrganonStandDensity(stand, variant);
                    Assert.IsTrue(densityEndOfStep.BasalAreaPerAcre > 0.0F);
                    Assert.IsTrue(densityEndOfStep.CrownCompetitionFactor > 0.0F);
                    Assert.IsTrue(densityEndOfStep.TreesPerAcre > 0.0F);

                    #pragma warning disable IDE0059 // Unnecessary assignment of a value
                    crownCompetitionByHeight = OrganonGrowth.GrowCrown(variant, stand, densityEndOfStep, calibrationBySpecies);
                    #pragma warning restore IDE0059 // Unnecessary assignment of a value
                    OrganonTest.Verify(ExpectedTreeChanges.NoDiameterOrHeightGrowth, stand, variant);
                    OrganonTest.Verify(calibrationBySpecies);
                }
            }
        }
Esempio n. 6
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);
                }
            }
        }
Esempio n. 7
0
        public override int GrowHeightBigSix(OrganonConfiguration configuration, OrganonStand stand, Trees trees, float[] crownCompetitionByHeight)
        {
            float P1;
            float P2;
            float P3;
            float P4;
            float P5;
            float P6;
            float P7;
            float P8;

            switch (trees.Species)
            {
            // Ritchie and Hann(1990) FRL Research Paper 54
            case FiaCode.AbiesGrandis:
                P1 = 1.0F;
                P2 = -0.0328142F;
                P3 = -0.0127851F;
                P4 = 1.0F;
                P5 = 6.19784F;
                P6 = 2.0F;
                P7 = 0.0F;
                P8 = 1.01F;
                break;

            case FiaCode.PseudotsugaMenziesii:
                P1 = 0.655258886F;
                P2 = -0.006322913F;
                P3 = -0.039409636F;
                P4 = 0.5F;
                P5 = 0.597617316F;
                P6 = 2.0F;
                P7 = 0.631643636F;
                P8 = 1.010018427F;
                break;

            case FiaCode.TsugaHeterophylla:
                P1 = 1.0F;
                P2 = -0.0384415F;
                P3 = -0.0144139F;
                P4 = 0.5F;
                P5 = 1.04409F;
                P6 = 2.0F;
                P7 = 0.0F;
                P8 = 1.03F;
                break;

            default:
                throw Trees.CreateUnhandledSpeciesException(trees.Species);
            }

            int oldTreeRecordCount = 0;

            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                if (trees.LiveExpansionFactor[treeIndex] <= 0.0F)
                {
                    trees.HeightGrowth[treeIndex] = 0.0F;
                    continue;
                }

                float growthEffectiveAge        = configuration.Variant.GetGrowthEffectiveAge(configuration, stand, trees, treeIndex, out float potentialHeightGrowth);
                float crownCompetitionIncrement = OrganonVariant.GetCrownCompetitionFactorByHeight(trees.Height[treeIndex], crownCompetitionByHeight);

                float crownRatio = trees.CrownRatio[treeIndex];
                float FCR        = -P5 *MathV.Pow(1.0F - crownRatio, P6) * MathV.Exp(P7 * MathF.Sqrt(crownCompetitionIncrement));

                float B0           = P1 * MathV.Exp(P2 * crownCompetitionIncrement);
                float B1           = MathV.Exp(P3 * MathV.Pow(crownCompetitionIncrement, P4));
                float MODIFER      = P8 * (B0 + (B1 - B0) * MathF.Exp(FCR)); // changed from MathV due to FCR of -91 being observed
                float CRADJ        = OrganonGrowth.GetCrownRatioAdjustment(crownRatio);
                float heightGrowth = potentialHeightGrowth * MODIFER * CRADJ;
                Debug.Assert(heightGrowth > 0.0F);
                trees.HeightGrowth[treeIndex] = heightGrowth;

                if (growthEffectiveAge > configuration.Variant.OldTreeAgeThreshold)
                {
                    ++oldTreeRecordCount;
                }
            }
            return(oldTreeRecordCount);
        }
Esempio n. 8
0
        public override void GrowDiameter(Trees trees, float growthMultiplier, float siteIndexFromDbh, OrganonStandDensity densityBeforeGrowth)
        {
            float B0;
            float B1;
            float B2;
            float B3;
            float B4;
            float B5;
            float B6;
            float K1;
            float K2;
            float K3;
            float K4;
            float speciesMultiplier = 0.8F;

            switch (trees.Species)
            {
            // Hann, Marshall, and Hanus(2006) FRL Research Contribution 49
            case FiaCode.PseudotsugaMenziesii:
                B0 = -5.34253119F;
                B1 = 1.098406840F;
                B2 = -0.05218621F;
                B3 = 1.01380810F;
                B4 = 0.91202025F;
                B5 = -0.01756220F;
                B6 = -0.05168923F;
                K1 = 6.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 1.0F;
                break;

            // Zumrawi and Hann(1993) FRL Research Contribution 4
            case FiaCode.AbiesGrandis:
                B0 = -2.34619F;
                B1 = 0.594640F;
                B2 = -0.000976092F;
                B3 = 1.12712F;
                B4 = 0.555333F;
                B5 = -0.0000290672F;
                B6 = -0.0470848F;
                K1 = 1.0F;
                K2 = 2.0F;
                K3 = 2.0F;
                K4 = 5.0F;
                speciesMultiplier = 0.8722F;
                break;

            // Unpublished Equation on File at OSU Dept.Forest Resources
            case FiaCode.TsugaHeterophylla:
                B0 = -4.87447412F;
                B1 = 0.4150723209F;
                B2 = -0.023744997F;
                B3 = 0.907837299F;
                B4 = 1.1346766989F;
                B5 = -0.015333503F;
                B6 = -0.03309787F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 1.0F;
                break;

            // Hann and Hanus(2002) OSU Department of Forest Management Internal Report #2
            case FiaCode.ThujaPlicata:
                B0 = -11.45456097F;
                B1 = 0.784133664F;
                B2 = -0.0261377888F;
                B3 = 0.70174783F;
                B4 = 2.057236260F;
                B5 = -0.00415440257F;
                B6 = 0.0F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.TaxusBrevifolia:
                B0 = -9.15835863F;
                B1 = 1.0F;
                B2 = -0.00000035F;
                B3 = 1.16688474F;
                B4 = 0.0F;
                B5 = 0.0F;
                B6 = -0.02F;
                K1 = 4000.0F;
                K2 = 4.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.ArbutusMenziesii:
                B0 = -8.84531757F;
                B1 = 1.5F;
                B2 = -0.0006F;
                B3 = 0.51225596F;
                B4 = 0.418129153F;
                B5 = -0.00355254593F;
                B6 = -0.0321315389F;
                K1 = 110.0F;
                K2 = 2.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 0.7928F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.AcerMacrophyllum:
                B0 = -3.41449922F;
                B1 = 1.0F;
                B2 = -0.05F;
                B3 = 0.0F;
                B4 = 0.324349277F;
                B5 = 0.0F;
                B6 = -0.0989519477F;
                K1 = 10.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Gould, Marshall, and Harrington(2008) West.J.Appl.For. 23: 26-33
            case FiaCode.QuercusGarryana:
                B0 = -7.81267986F;
                B1 = 1.405616529F;
                B2 = -0.0603105850F;
                B3 = 0.64286007F;
                B4 = 1.037687142F;
                B5 = 0.0F;
                B6 = -0.0787012218F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 1.0F;
                break;

            // Hann and Hanus(2002) OSU Department of Forest Management Internal Report #1
            case FiaCode.AlnusRubra:
                B0 = -4.39082007F;
                B1 = 1.0F;
                B2 = -0.0945057147F;
                B3 = 1.06867026F;
                B4 = 0.685908029F;
                B5 = -0.00586331028F;
                B6 = 0.0F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.CornusNuttallii:
            case FiaCode.Salix:
                B0 = -8.08352683F;
                B1 = 1.0F;
                B2 = -0.00000035F;
                B3 = 0.31176647F;
                B4 = 0.0F;
                B5 = 0.0F;
                B6 = -0.0730788052F;
                K1 = 4000.0F;
                K2 = 4.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            default:
                throw Trees.CreateUnhandledSpeciesException(trees.Species);
            }

            speciesMultiplier *= growthMultiplier;
            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                if (trees.LiveExpansionFactor[treeIndex] <= 0.0F)
                {
                    trees.DbhGrowth[treeIndex] = 0.0F;
                    continue;
                }

                float dbhInInches          = trees.Dbh[treeIndex];
                float basalAreaLarger      = densityBeforeGrowth.GetBasalAreaLarger(dbhInInches);
                float crownRatio           = trees.CrownRatio[treeIndex];
                float LNDG                 = B0 + B1 * MathV.Ln(dbhInInches + K1) + B2 * MathV.Pow(dbhInInches, K2) + B3 * MathV.Ln((crownRatio + 0.2F) / 1.2F) + B4 * MathV.Ln(siteIndexFromDbh) + B5 * (MathV.Pow(basalAreaLarger, K3) / MathV.Ln(dbhInInches + K4)) + B6 * MathF.Sqrt(basalAreaLarger);
                float crownRatioAdjustment = OrganonGrowth.GetCrownRatioAdjustment(crownRatio);
                trees.DbhGrowth[treeIndex] = speciesMultiplier * MathV.Exp(LNDG) * crownRatioAdjustment;
                Debug.Assert(trees.DbhGrowth[treeIndex] > 0.0F);
                Debug.Assert(trees.DbhGrowth[treeIndex] < Constant.Maximum.DiameterIncrementInInches);
            }
        }
Esempio n. 9
0
        public override void ReduceExpansionFactors(OrganonStand stand, OrganonStandDensity densityBeforeGrowth, Trees trees, float fertilizationExponent)
        {
            // RAP MORTALITY
            float B0;
            float B1;
            float B2;
            float B3;
            float B4;
            float B5;
            float POW = 0.2F;

            switch (trees.Species)
            {
            // RA Coefficients from Hann, Bluhm, and Hibbs New Red Alder Equation
            case FiaCode.AlnusRubra:
                B0  = -4.333150734F;
                B1  = -0.9856713799F;
                B2  = 0.0F;
                B3  = -2.583317081F;
                B4  = 0.0369852164F;
                B5  = 0.0394546978F;
                POW = 1.0F;
                break;

            // Hann, Marshall, and Hanus(2006) FRL Research Contribution 49
            case FiaCode.PseudotsugaMenziesii:
                B0 = -3.12161659F;
                B1 = -0.44724396F;
                B2 = 0.0F;
                B3 = -2.48387172F;
                B4 = 0.01843137F;
                B5 = 0.01353918F;
                break;

            // Hann, Marshall, Hanus(2003) FRL Research Contribution 40
            case FiaCode.TsugaHeterophylla:
                B0 = -0.761609F;
                B1 = -0.529366F;
                B2 = 0.0F;
                B3 = -4.74019F;
                B4 = 0.0119587F;
                B5 = 0.00756365F;
                break;

            // WH of Hann, Marshall, Hanus(2003) FRL Research Contribution 40
            case FiaCode.ThujaPlicata:
                B0 = -0.761609F;
                B1 = -0.529366F;
                B2 = 0.0F;
                B3 = -4.74019F;
                B4 = 0.0119587F;
                B5 = 0.00756365F;
                break;

            // Hann and Hanus(2001) FRL Research Contribution 34
            case FiaCode.AcerMacrophyllum:
                B0 = -2.976822456F;
                B1 = 0.0F;
                B2 = 0.0F;
                B3 = -6.223250962F;
                B4 = 0.0F;
                B5 = 0.0F;
                break;

            // Hann and Hanus(2001) FRL Research Contribution 34
            case FiaCode.CornusNuttallii:
                B0 = -3.020345211F;
                B1 = 0.0F;
                B2 = 0.0F;
                B3 = -8.467882343F;
                B4 = 0.013966388F;
                B5 = 0.009461545F;
                break;

            // best guess
            case FiaCode.Salix:
                B0 = -1.386294361F;
                B1 = 0.0F;
                B2 = 0.0F;
                B3 = 0.0F;
                B4 = 0.0F;
                B5 = 0.0F;
                break;

            default:
                throw Trees.CreateUnhandledSpeciesException(trees.Species);
            }

            // BUGBUG: Fortran code didn't use red alder site index for red alder and used hemlock site index for all conifers, not just hemlock and redcedar
            float siteIndex = stand.HemlockSiteIndex; // interpreted as Douglas-fir site index

            if (trees.Species == FiaCode.AlnusRubra)
            {
                siteIndex = stand.SiteIndex;
            }
            else if ((trees.Species == FiaCode.TsugaHeterophylla) || (trees.Species == FiaCode.ThujaPlicata))
            {
                siteIndex = OrganonVariantNwo.ToHemlockSiteIndexStatic(siteIndex); // convert from Douglas-fir site index to actual hemlock site inde
            }

            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                if (trees.LiveExpansionFactor[treeIndex] <= 0.0F)
                {
                    continue;
                }
                float dbhInInches     = trees.Dbh[treeIndex];
                float basalAreaLarger = densityBeforeGrowth.GetBasalAreaLarger(dbhInInches);
                float crownRatio      = trees.CrownRatio[treeIndex];
                float PMK             = B0 + B1 * dbhInInches + B2 * dbhInInches * dbhInInches + B3 * crownRatio + B4 * siteIndex + B5 * basalAreaLarger + fertilizationExponent;

                float XPM = 1.0F / (1.0F + MathV.Exp(-PMK));
                float survivalProbability = POW == 1.0 ? 1.0F - XPM : MathV.Pow(1.0F - XPM, POW); // RAP is the only variant using unfertlized POW != 1
                survivalProbability *= OrganonGrowth.GetCrownRatioAdjustment(crownRatio);
                Debug.Assert(survivalProbability >= 0.0F);
                Debug.Assert(survivalProbability <= 1.0F);

                float newLiveExpansionFactor = survivalProbability * trees.LiveExpansionFactor[treeIndex];
                if (newLiveExpansionFactor < 0.00001F)
                {
                    newLiveExpansionFactor = 0.0F;
                }
                float mortalityExpansionFactor = trees.LiveExpansionFactor[treeIndex] - newLiveExpansionFactor;

                trees.DeadExpansionFactor[treeIndex] = mortalityExpansionFactor;
                trees.LiveExpansionFactor[treeIndex] = newLiveExpansionFactor;
            }
        }
Esempio n. 10
0
        public override int GrowHeightBigSix(OrganonConfiguration configuration, OrganonStand stand, Trees trees, float[] crownCompetitionByHeight)
        {
            // WEIGHTED CENTRAL PAI PROCEDURE PARAMETERS FOR RED ALDER
            float P1;
            float P2;
            float P3;
            float P4;
            float P5;
            float P6;
            float P7;
            float P8;

            switch (trees.Species)
            {
            // Hann, Bluhm, and Hibbs Red Alder Plantation Analysis
            case FiaCode.AlnusRubra:
                P1 = 0.809837005F;
                P2 = -0.0134163653F;
                P3 = -0.0609398629F;
                P4 = 0.5F;
                P5 = 1.0F;
                P6 = 2.0F;
                P7 = 0.1469442410F;
                P8 = 1.0476380753F;
                break;

            // Hann, Marshall, and Hanus(2006) FRL Research Contribution ??
            case FiaCode.PseudotsugaMenziesii:
                P1 = 0.655258886F;
                P2 = -0.006322913F;
                P3 = -0.039409636F;
                P4 = 0.5F;
                P5 = 0.597617316F;
                P6 = 2.0F;
                P7 = 0.631643636F;
                P8 = 1.010018427F;
                break;

            // Johnson(2002) Willamette Industries Report
            case FiaCode.TsugaHeterophylla:
                P1 = 1.0F;
                P2 = -0.0384415F;
                P3 = -0.0144139F;
                P4 = 0.5F;
                P5 = 1.04409F;
                P6 = 2.0F;
                P7 = 0.0F;
                P8 = 1.03F;
                break;

            default:
                throw Trees.CreateUnhandledSpeciesException(trees.Species);
            }

            int oldTreeRecordCount = 0;

            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                if (trees.LiveExpansionFactor[treeIndex] <= 0.0F)
                {
                    trees.HeightGrowth[treeIndex] = 0.0F;
                    continue;
                }

                float growthEffectiveAge        = configuration.Variant.GetGrowthEffectiveAge(configuration, stand, trees, treeIndex, out float potentialHeightGrowth);
                float crownCompetitionIncrement = OrganonVariant.GetCrownCompetitionFactorByHeight(trees.Height[treeIndex], crownCompetitionByHeight);

                float crownRatio = trees.CrownRatio[treeIndex];
                float FCR        = -P5 *MathV.Pow(1.0F - crownRatio, P6) * MathV.Exp(P7 * MathF.Sqrt(crownCompetitionIncrement));

                float B0           = P1 * MathV.Exp(P2 * crownCompetitionIncrement);
                float B1           = MathV.Exp(P3 * MathV.Pow(crownCompetitionIncrement, P4));
                float MODIFER      = P8 * (B0 + (B1 - B0) * MathV.Exp(FCR));
                float CRADJ        = OrganonGrowth.GetCrownRatioAdjustment(crownRatio);
                float heightGrowth = potentialHeightGrowth * MODIFER * CRADJ;
                Debug.Assert(heightGrowth > 0.0F);
                trees.HeightGrowth[treeIndex] = heightGrowth;

                if (growthEffectiveAge > configuration.Variant.OldTreeAgeThreshold)
                {
                    ++oldTreeRecordCount;
                }
            }
            return(oldTreeRecordCount);
        }
Esempio n. 11
0
        public override void GrowDiameter(Trees trees, float growthMultiplier, float siteIndexFromDbh, OrganonStandDensity densityBeforeGrowth)
        {
            // These species were annualized by adding ln(0.2) to the intercept terms: DF, WH, RC, ACMA3, Cornus, Salix
            float B0;
            float B1;
            float B2;
            float B3;
            float B4;
            float B5;
            float B6;
            float K1;
            float K2;
            float K3;
            float K4;
            float speciesMultiplier = 0.8F;

            switch (trees.Species)
            {
            // Hann, Bluhm, and Hibbs Red Alder Plantation Analysis
            case FiaCode.AlnusRubra:
                B0 = -4.622849554F;
                B1 = 0.5112200516F;
                B2 = -0.1040194568F;
                B3 = 0.9536538143F;
                B4 = 1.0659344724F;
                B5 = -0.0193047405F;
                B6 = -0.0773539455F;
                K1 = 1.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 1.0F;
                speciesMultiplier = 1.0F;
                break;

            // Hann, Marshall, and Hanus(2006) FRL Research Contribution ??
            case FiaCode.PseudotsugaMenziesii:
                B0 = -6.95196910F;
                B1 = 1.098406840F;
                B2 = -0.05218621F;
                B3 = 1.01380810F;
                B4 = 0.91202025F;
                B5 = -0.01756220F;
                B6 = -0.05168923F;
                K1 = 6.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 1.0F;
                break;

            // Unpublished equation on file at OSU Deptartment of Forest Resources
            case FiaCode.TsugaHeterophylla:
                B0 = -6.48391203F;
                B1 = 0.4150723209F;
                B2 = -0.023744997F;
                B3 = 0.907837299F;
                B4 = 1.1346766989F;
                B5 = -0.015333503F;
                B6 = -0.03309787F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                speciesMultiplier = 1.0F;
                break;

            // Hann and Hanus(2002) OSU Department of Forest Management Internal Report #2
            case FiaCode.ThujaPlicata:
                B0 = -13.06399888F;
                B1 = 0.784133664F;
                B2 = -0.0261377888F;
                B3 = 0.70174783F;
                B4 = 2.057236260F;
                B5 = -0.00415440257F;
                B6 = 0.0F;
                K1 = 5.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.AcerMacrophyllum:
                B0 = -5.02393713F;
                B1 = 1.0F;
                B2 = -0.05F;
                B3 = 0.0F;
                B4 = 0.324349277F;
                B5 = 0.0F;
                B6 = -0.0989519477F;
                K1 = 10.0F;
                K2 = 1.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            // Hann and Hanus(2002) FRL Research Contribution 39
            case FiaCode.CornusNuttallii:
            case FiaCode.Salix:
                B0 = -9.69296474F;
                B1 = 1.0F;
                B2 = -0.00000035F;
                B3 = 0.31176647F;
                B4 = 0.0F;
                B5 = 0.0F;
                B6 = -0.0730788052F;
                K1 = 4000.0F;
                K2 = 4.0F;
                K3 = 1.0F;
                K4 = 2.7F;
                break;

            default:
                throw Trees.CreateUnhandledSpeciesException(trees.Species);
            }

            speciesMultiplier *= growthMultiplier;
            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                if (trees.LiveExpansionFactor[treeIndex] <= 0.0F)
                {
                    trees.DbhGrowth[treeIndex] = 0.0F;
                    continue;
                }

                float dbhInInches          = trees.Dbh[treeIndex];
                float basalAreaLarger      = densityBeforeGrowth.GetBasalAreaLarger(dbhInInches);
                float crownRatio           = trees.CrownRatio[treeIndex];
                float LNDG                 = B0 + B1 * MathV.Ln(dbhInInches + K1) + B2 * MathV.Pow(dbhInInches, K2) + B3 * MathV.Ln((crownRatio + 0.2F) / 1.2F) + B4 * MathV.Ln(siteIndexFromDbh) + B5 * (MathV.Pow(basalAreaLarger, K3) / MathV.Ln(dbhInInches + K4)) + B6 * MathF.Sqrt(basalAreaLarger);
                float crownRatioAdjustment = OrganonGrowth.GetCrownRatioAdjustment(crownRatio);
                trees.DbhGrowth[treeIndex] = speciesMultiplier * MathV.Exp(LNDG) * crownRatioAdjustment;
                Debug.Assert(trees.DbhGrowth[treeIndex] > 0.0F);
                Debug.Assert(trees.DbhGrowth[treeIndex] < Constant.Maximum.DiameterIncrementInInches);
            }
        }