public static Vector128 <float> GetFlewellingGrowthEffectiveAge(SiteConstants site, float timeStepInYears, Vector128 <float> treeHeight, out Vector128 <float> potentialHeightGrowth) { // for now, just a vector to scalar shim for caller convenience // TODO: SIMD implementation float growthEffectiveAge0 = WesternHemlock.GetFlewellingGrowthEffectiveAge(site, timeStepInYears, Avx.Extract(treeHeight, 0), out float potentialHeightGrowth0); float growthEffectiveAge1 = WesternHemlock.GetFlewellingGrowthEffectiveAge(site, timeStepInYears, Avx.Extract(treeHeight, 0), out float potentialHeightGrowth1); float growthEffectiveAge2 = WesternHemlock.GetFlewellingGrowthEffectiveAge(site, timeStepInYears, Avx.Extract(treeHeight, 0), out float potentialHeightGrowth2); float growthEffectiveAge3 = WesternHemlock.GetFlewellingGrowthEffectiveAge(site, timeStepInYears, Avx.Extract(treeHeight, 0), out float potentialHeightGrowth3); potentialHeightGrowth = Vector128.Create(potentialHeightGrowth0, potentialHeightGrowth1, potentialHeightGrowth2, potentialHeightGrowth3); Vector128 <float> growthEffectiveAge = Vector128.Create(growthEffectiveAge0, growthEffectiveAge1, growthEffectiveAge2, growthEffectiveAge3); return(growthEffectiveAge); }
/// <summary> /// Calculate western hemlock growth effective age and potential height growth using Flewelling's model for dominant individuals. /// </summary> /// <param name="site">Site growth constants.</param> /// <param name="treeHeight">Height of tree.</param> /// <param name="timeStepInYears"></param> /// <param name="growthEffectiveAge">Growth effective age of tree.</param> /// <param name="potentialHeightGrowth">Potential height growth increment in feet.</param> public static float GetFlewellingGrowthEffectiveAge(SiteConstants site, float timeStepInYears, float treeHeight, out float potentialHeightGrowth) { // For Western Hemlock compute Growth Effective Age and 5-year potential // or 1-year height growth using the western hemlock top height curves of // Flewelling.These subroutines are required: // SITECV_F computes top height from site and age // SITEF_C computes model parameters // SITEF_SI calculates an approximate psi for a given site // Note: Flewelling's curves are metric. // Site Index is not adjusted for stump height. float HTM = Constant.MetersPerFoot * treeHeight; // find growth effective age within precision of 0.01 years float HTOP; float AGE = 1.0F; float growthEffectiveAge; for (int index = 0; index < 4; ++index) { do { AGE += 100.0F / MathV.Exp10(index); if (AGE > 500.0F) { growthEffectiveAge = 500.0F; WesternHemlock.SITECV_F(site, growthEffectiveAge, out float XHTOP1); WesternHemlock.SITECV_F(site, growthEffectiveAge + timeStepInYears, out float XHTOP2); potentialHeightGrowth = Constant.FeetPerMeter * (XHTOP2 - XHTOP1); return(growthEffectiveAge); } WesternHemlock.SITECV_F(site, AGE, out HTOP); }while (HTOP < HTM); AGE -= 100.0F / MathV.Exp10(index); } growthEffectiveAge = AGE; // Compute top height and potential height growth WesternHemlock.SITECV_F(site, growthEffectiveAge + timeStepInYears, out HTOP); float potentialTopHeightInFeet = Constant.FeetPerMeter * HTOP; potentialHeightGrowth = potentialTopHeightInFeet - treeHeight; return(growthEffectiveAge); }