Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        /// Computes old growth index?
        /// </summary>
        /// <param name="stand">Stand data.</param>
        /// <param name="incrementMultiplier">Zero or minus one, usually zero.</param>
        /// <param name="OG">Old growth indicator.</param>
        /// <remarks>
        /// Supports only to 99 inch DBH.
        /// </remarks>
        public static float GetOldGrowthIndicator(OrganonVariant variant, OrganonStand stand)
        {
            // TODO: move diameter class and stand density information into stand for simplified state management and reduced compute
            int diameterClasses = 100;

            float[] treesPerAcreByDiameterClass   = new float[diameterClasses];
            float[] weightedDbhByDiameterClass    = new float[diameterClasses];
            float[] weightedHeightByDiameterClass = new float[diameterClasses];
            foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values)
            {
                if (variant.IsBigSixSpecies(treesOfSpecies.Species) == false)
                {
                    continue;
                }
                for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex)
                {
                    float dbhInInches = treesOfSpecies.Dbh[treeIndex];
                    int   dbhIndex    = (int)dbhInInches;
                    if (dbhIndex >= treesPerAcreByDiameterClass.Length)
                    {
                        dbhIndex = treesPerAcreByDiameterClass.Length - 1;
                    }

                    float expansionFactor = treesOfSpecies.LiveExpansionFactor[treeIndex];
                    Debug.Assert(expansionFactor >= 0.0F);
                    Debug.Assert(expansionFactor <= Constant.Maximum.ExpansionFactor);

                    treesPerAcreByDiameterClass[dbhIndex]   += expansionFactor;
                    weightedDbhByDiameterClass[dbhIndex]    += expansionFactor * dbhInInches;
                    weightedHeightByDiameterClass[dbhIndex] += expansionFactor * treesOfSpecies.Height[treeIndex];
                }
            }

            float largestFiveTpaWeightedHeight = 0.0F;
            float largestFiveTpaWeightedDbh    = 0.0F;
            float largeTreeTpa = 0.0F;

            for (int dbhIndex = weightedHeightByDiameterClass.Length - 1; dbhIndex >= 0; --dbhIndex)
            {
                largestFiveTpaWeightedHeight += weightedHeightByDiameterClass[dbhIndex];
                largestFiveTpaWeightedDbh    += weightedDbhByDiameterClass[dbhIndex];
                largeTreeTpa += treesPerAcreByDiameterClass[dbhIndex];
                if (largeTreeTpa > 5.0F)
                {
                    float TRDIFF = treesPerAcreByDiameterClass[dbhIndex] - (largeTreeTpa - 5.0F);
                    largestFiveTpaWeightedHeight = largestFiveTpaWeightedHeight - weightedHeightByDiameterClass[dbhIndex] + ((weightedHeightByDiameterClass[dbhIndex] / treesPerAcreByDiameterClass[dbhIndex]) * TRDIFF);
                    largestFiveTpaWeightedDbh    = largestFiveTpaWeightedDbh - weightedDbhByDiameterClass[dbhIndex] + ((weightedDbhByDiameterClass[dbhIndex] / treesPerAcreByDiameterClass[dbhIndex]) * TRDIFF);
                    largeTreeTpa = 5.0F;
                    break;
                }
            }

            float oldGrowthIndicator = 0.0F;

            if (largeTreeTpa > 0.0F)
            {
                float HT5  = largestFiveTpaWeightedHeight / largeTreeTpa;
                float DBH5 = largestFiveTpaWeightedDbh / largeTreeTpa;
                oldGrowthIndicator = DBH5 * HT5 / 10000.0F;
                Debug.Assert(oldGrowthIndicator >= 0.0F);
                Debug.Assert(oldGrowthIndicator <= 1000.0F);
            }
            return(oldGrowthIndicator);
        }