示例#1
0
        private float CalculateWaterLimitation(int leafOnStart, int leafOnEnd)
        {
            // return 1 if effect is disabled
            if (mRUspecies.Species.EstablishmentParameters.PsiMin >= 0.0F)
            {
                return(1.0F);
            }

            float      minimumPsiMPa = mRUspecies.Species.EstablishmentParameters.PsiMin;
            WaterCycle water         = mRUspecies.RU.WaterCycle;

            // two week (14 days) running average of actual psi-values on the resource unit
            const int daysToAverage = 14;

            float[] soilWaterPotentialsInAverage = new float[daysToAverage];
            float   currentPsiSum = 0.0F;

            float miniumumMovingAverage = Single.MaxValue;
            int   daysInYear            = mRUspecies.RU.Climate.GetDaysInYear();

            for (int dayOfYear = 0, averageIndex = 0; dayOfYear < daysInYear; ++dayOfYear)
            {
                // running average: remove oldest item, add new item in a ringbuffer
                currentPsiSum -= soilWaterPotentialsInAverage[averageIndex];
                soilWaterPotentialsInAverage[averageIndex] = water.SoilWaterPsi[dayOfYear];
                currentPsiSum += soilWaterPotentialsInAverage[averageIndex];

                if (dayOfYear >= leafOnStart && dayOfYear <= leafOnEnd)
                {
                    float currentPsiAverage = dayOfYear > 0 ? currentPsiSum / MathF.Min(dayOfYear, daysToAverage) : currentPsiSum;
                    miniumumMovingAverage = MathF.Min(miniumumMovingAverage, currentPsiAverage);
                }

                // move to next value in the buffer
                averageIndex = ++averageIndex % daysToAverage;
            }

            if (miniumumMovingAverage > 1000.0)
            {
                return(1.0F); // invalid vegetation period?
            }

            // calculate the response of the species to this value of psi (see also Species.GetSoilWaterModifier())
            float meanPsiMPa = 0.001F * miniumumMovingAverage; // convert to MPa
            float result     = Maths.Limit((meanPsiMPa - minimumPsiMPa) / (-0.015F - minimumPsiMPa), 0.0F, 1.0F);

            return(result);
        }
示例#2
0
        protected override void LogYear(Model model, SqliteCommand insertRow)
        {
            // global condition
            if ((this.mYearFilter.IsEmpty == false) && (mYearFilter.Evaluate(model.CurrentYear) == 0.0))
            {
                return;
            }

            int   resourceUnitCount = 0;
            int   snowDays = 0;
            float evapotranspiration = 0.0F, runoff = 0.0F, rad = 0.0F, snowRad = 0.0F, precip = 0.0F;
            float stockable = 0.0F, stocked = 0.0F;

            foreach (ResourceUnit ru in model.Landscape.ResourceUnits)
            {
                if (ru.EnvironmentID == -1)
                {
                    continue; // do not include if out of project area
                }

                bool logResourceUnits = true;
                // switch off details if this is indicated in the conditionRU option
                if (this.mResourceUnitFilter.IsEmpty == false)
                {
                    Debug.Assert(this.mResourceUnitFilter.Wrapper != null);
                    ((ResourceUnitWrapper)this.mResourceUnitFilter.Wrapper).ResourceUnit = ru;
                    logResourceUnits = this.mResourceUnitFilter.Evaluate(model.CurrentYear) != 0.0;
                }

                WaterCycle wc = ru.WaterCycle;
                if (logResourceUnits)
                {
                    insertRow.Parameters[0].Value  = model.CurrentYear;
                    insertRow.Parameters[1].Value  = ru.ResourceUnitGridIndex;
                    insertRow.Parameters[2].Value  = ru.EnvironmentID;
                    insertRow.Parameters[3].Value  = ru.AreaWithTrees / Constant.RUArea;
                    insertRow.Parameters[4].Value  = ru.AreaInLandscape / Constant.RUArea;
                    insertRow.Parameters[5].Value  = ru.Climate.GetTotalPrecipitationInCurrentYear();
                    insertRow.Parameters[6].Value  = wc.TotalEvapotranspiration;
                    insertRow.Parameters[7].Value  = wc.TotalRunoff;
                    insertRow.Parameters[8].Value  = wc.SnowDays;
                    insertRow.Parameters[9].Value  = ru.Climate.TotalAnnualRadiation;
                    insertRow.Parameters[10].Value = wc.SnowDayRadiation;
                    insertRow.ExecuteNonQuery();
                }
                ++resourceUnitCount;
                stockable          += ru.AreaInLandscape;
                stocked            += ru.AreaWithTrees;
                precip             += ru.Climate.GetTotalPrecipitationInCurrentYear();
                evapotranspiration += wc.TotalEvapotranspiration;
                runoff             += wc.TotalRunoff;
                snowDays           += (int)wc.SnowDays;
                rad     += ru.Climate.TotalAnnualRadiation;
                snowRad += wc.SnowDayRadiation;
            }

            // write landscape sums
            if (resourceUnitCount == 0)
            {
                return;
            }
            insertRow.Parameters[0].Value  = model.CurrentYear; // codes -1/-1 for landscape level
            insertRow.Parameters[1].Value  = -1;
            insertRow.Parameters[2].Value  = -1;
            insertRow.Parameters[3].Value  = stocked / resourceUnitCount / Constant.RUArea;
            insertRow.Parameters[4].Value  = stockable / resourceUnitCount / Constant.RUArea;
            insertRow.Parameters[5].Value  = precip / resourceUnitCount; // mean precip
            insertRow.Parameters[6].Value  = evapotranspiration / resourceUnitCount;
            insertRow.Parameters[7].Value  = runoff / resourceUnitCount;
            insertRow.Parameters[8].Value  = snowDays / resourceUnitCount;
            insertRow.Parameters[9].Value  = rad / resourceUnitCount;
            insertRow.Parameters[10].Value = snowRad / resourceUnitCount;
            insertRow.ExecuteNonQuery();
        }