Пример #1
0
        private void OnCLEMUpdatePasture(object sender, EventArgs e)
        {
            this.Status = ActivityStatus.Ignored;
            if (PastureDataList != null)
            {
                this.Status = ActivityStatus.NotNeeded;
                double growth = 0;

                //// method is performed on last day of month but needs to work with next month's details
                //int year = Clock.Today.AddDays(1).Year;
                //int month = Clock.Today.AddDays(1).Month;

                int year  = Clock.Today.Year;
                int month = Clock.Today.Month;

                //Get this months pasture data from the pasture data list
                PastureDataType pasturedata = PastureDataList.Where(a => a.Year == year && a.Month == month).FirstOrDefault();

                growth = pasturedata.Growth;
                //TODO: check units from input files.
                // convert from kg/ha to kg/area unit
                growth *= unitsOfArea2Ha;

                Cover = pasturedata.Cover;

                if (growth > 0)
                {
                    this.Status = ActivityStatus.Success;
                    GrazeFoodStorePool newPasture = new GrazeFoodStorePool
                    {
                        Age = 0
                    };
                    newPasture.Set(growth * Area);
                    newPasture.Growth   = growth * Area;
                    newPasture.Nitrogen = this.LinkedNativeFoodType.GreenNitrogen;
                    newPasture.DMD      = newPasture.Nitrogen * LinkedNativeFoodType.NToDMDCoefficient + LinkedNativeFoodType.NToDMDIntercept;
                    newPasture.DMD      = Math.Min(100, Math.Max(LinkedNativeFoodType.MinimumDMD, newPasture.DMD));
                    this.LinkedNativeFoodType.Add(newPasture, this, "Growth");
                }
            }
            else
            {
                this.Status = ActivityStatus.Critical;
                throw new Exception("No pasture data is available for [a=" + this.Name + "]\nCheck that data is available for specified soil id etc. ");
            }

            // report activity performed.
            ActivityPerformedEventArgs activitye = new ActivityPerformedEventArgs
            {
                Activity = new BlankActivity()
                {
                    Status = ZoneCLEM.IsEcologicalIndicatorsCalculationMonth()? ActivityStatus.Calculation: ActivityStatus.Success,
                    Name   = this.Name
                }
            };

            activitye.Activity.SetGuID(this.UniqueID);
            this.OnActivityPerformed(activitye);
        }
Пример #2
0
        private void OnCLEMUpdatePasture(object sender, EventArgs e)
        {
            this.Status = ActivityStatus.Ignored;
            if (PastureDataList != null)
            {
                this.Status = ActivityStatus.NotNeeded;
                double growth = 0;

                //Get this months pasture data from the pasture data list
                PastureDataType pasturedata = PastureDataList.Where(a => a.Year == Clock.Today.Year && a.Month == Clock.Today.Month).FirstOrDefault();

                growth = pasturedata.Growth;
                //TODO: check units from input files.
                // convert from kg/ha to kg/area unit
                growth *= unitsOfArea2Ha;

                LinkedNativeFoodType.CurrentEcologicalIndicators.Rainfall      += pasturedata.Rainfall;
                LinkedNativeFoodType.CurrentEcologicalIndicators.Erosion       += pasturedata.SoilLoss;
                LinkedNativeFoodType.CurrentEcologicalIndicators.Runoff        += pasturedata.Runoff;
                LinkedNativeFoodType.CurrentEcologicalIndicators.Cover         += pasturedata.Cover;
                LinkedNativeFoodType.CurrentEcologicalIndicators.TreeBasalArea += pasturedata.TreeBA;

                if (growth > 0)
                {
                    this.Status = ActivityStatus.Success;
                    GrazeFoodStorePool newPasture = new GrazeFoodStorePool
                    {
                        Age = 0
                    };
                    newPasture.Set(growth * Area);
                    newPasture.Nitrogen = this.LinkedNativeFoodType.GreenNitrogen;
                    newPasture.DMD      = newPasture.Nitrogen * LinkedNativeFoodType.NToDMDCoefficient + LinkedNativeFoodType.NToDMDIntercept;
                    newPasture.DMD      = Math.Min(100, Math.Max(LinkedNativeFoodType.MinimumDMD, newPasture.DMD));
                    newPasture.Growth   = newPasture.Amount;
                    this.LinkedNativeFoodType.Add(newPasture, this, "", "Growth");
                }
            }

            // report activity performed.
            ActivityPerformedEventArgs activitye = new ActivityPerformedEventArgs
            {
                Activity = new BlankActivity()
                {
                    Status = ZoneCLEM.IsEcologicalIndicatorsCalculationMonth()? ActivityStatus.Calculation: ActivityStatus.Success,
                    Name   = this.Name
                }
            };

            activitye.Activity.SetGuID(this.UniqueID);
            this.OnActivityPerformed(activitye);
        }
Пример #3
0
        private void SetupStartingPasturePools(double StartingGrowth)
        {
            // Initial biomass
            double amountToAdd = Area * StartingGrowth;

            if (amountToAdd <= 0)
            {
                return;
            }

            // Set up pasture pools to start run based on month and user defined pasture properties
            // Locates the previous five months where growth occurred (Nov-Mar) and applies decomposition to current month
            // This months growth will not be included.

            int    month              = Clock.Today.Month;
            int    monthCount         = 0;
            int    includedMonthCount = 0;
            double propBiomass        = 1.0;
            double currentN           = LinkedNativeFoodType.GreenNitrogen;
            // NABSA changes N by 0.8 for particular months. Not needed here as decay included.
            double currentDMD = currentN * LinkedNativeFoodType.NToDMDCoefficient + LinkedNativeFoodType.NToDMDIntercept;

            currentDMD = Math.Max(LinkedNativeFoodType.MinimumDMD, currentDMD);
            LinkedNativeFoodType.Pools.Clear();

            List <GrazeFoodStorePool> newPools = new List <GrazeFoodStorePool>();

            while (includedMonthCount < 5)
            {
                if (month == 0)
                {
                    month = 12;
                }
                if (month <= 3 | month >= 11)
                {
                    // add new pool
                    newPools.Add(new GrazeFoodStorePool()
                    {
                        Age            = monthCount,
                        Nitrogen       = currentN,
                        DMD            = currentDMD,
                        StartingAmount = propBiomass
                    });
                    includedMonthCount++;
                }
                propBiomass *= 1 - LinkedNativeFoodType.DetachRate;
                currentN    -= LinkedNativeFoodType.DecayNitrogen;
                currentN     = Math.Max(currentN, LinkedNativeFoodType.MinimumNitrogen);
                currentDMD  *= 1 - LinkedNativeFoodType.DecayDMD;
                currentDMD   = Math.Max(currentDMD, LinkedNativeFoodType.MinimumDMD);
                monthCount++;
                month--;
            }

            // assign pasture biomass to pools based on proportion of total
            double total = newPools.Sum(a => a.StartingAmount);

            foreach (var pool in newPools)
            {
                pool.Set(amountToAdd * (pool.StartingAmount / total));
                pool.Growth = amountToAdd * (pool.StartingAmount / total);
            }

            // Previously: remove this months growth from pool age 0 to keep biomass at approximately setup.
            // But as updates happen at the end of the month, the fist months biomass is never added so stay with 0 or delete following section
            // Get this months growth
            //Get this months pasture data from the pasture data list
            PastureDataType pasturedata = PastureDataList.Where(a => a.Year == Clock.StartDate.Year && a.Month == Clock.StartDate.Month).FirstOrDefault();
            //double growth = ; // GRASPFile.Get(xxxxxxxxx)

            double thisMonthsGrowth = pasturedata.Growth;

            if (thisMonthsGrowth > 0)
            {
                GrazeFoodStorePool thisMonth = newPools.Where(a => a.Age == 0).FirstOrDefault() as GrazeFoodStorePool;
                if (thisMonth != null)
                {
                    thisMonth.Set(Math.Max(0, thisMonth.Amount - thisMonthsGrowth));
                }
            }

            // Add to pasture. This will add pool to pasture available store.
            foreach (var pool in newPools)
            {
                string reason = "Initialise";
                if (newPools.Count() > 1)
                {
                    reason = "Initialise pool " + pool.Age.ToString();
                }
                LinkedNativeFoodType.Add(pool, this.Name, reason);
            }
        }
Пример #4
0
        private void OnCLEMInitialiseResource(object sender, EventArgs e)
        {
            // activity is performed in CLEMUpdatePasture not CLEMGetResources and has no labour
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            // locate Land Type resource for this forage.
            LinkedLandItem     = Resources.FindResourceType <Land, LandType>(this, LandTypeNameToUse, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop);
            LandConditionIndex = FindAllDescendants <RelationshipRunningValue>().Where(a => (new string[] { "lc", "landcondition", "landcon", "landconditionindex" }).Contains(a.Name.ToLower())).FirstOrDefault() as RelationshipRunningValue;
            GrassBasalArea     = FindAllDescendants <RelationshipRunningValue>().Where(a => (new string[] { "gba", "basalarea", "grassbasalarea" }).Contains(a.Name.ToLower())).FirstOrDefault() as RelationshipRunningValue;
            filePasture        = zoneCLEM.Parent.FindAllDescendants().Where(a => a.Name == PastureDataReader).FirstOrDefault() as IFilePasture;

            if (LandConditionIndex is null || GrassBasalArea is null || filePasture is null)
            {
                return;
            }

            LandType land = null;

            if (filePasture != null)
            {
                // check that database has region id and land id
                ZoneCLEM clem = FindAncestor <ZoneCLEM>();
                int      recs = filePasture.RecordsFound((filePasture as FileSQLitePasture).RegionColumnName, clem.ClimateRegion);
                if (recs == 0)
                {
                    throw new ApsimXException(this, $"No pasture production records were located by [x={(filePasture as Model).Name}] for [a={this.Name}] given [Region id] = [{clem.ClimateRegion}] as specified in [{clem.Name}]");
                }

                land = Resources.FindResourceType <Land, LandType>(this, LandTypeNameToUse, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop);
                if (land != null)
                {
                    recs = filePasture.RecordsFound((filePasture as FileSQLitePasture).LandIdColumnName, land.SoilType);
                    if (recs == 0)
                    {
                        throw new ApsimXException(this, $"No pasture production records were located by [x={(filePasture as Model).Name}] for [a={this.Name}] given [Land id] = [{land.SoilType}] as specified in [{land.Name}] used to manage the pasture");
                    }
                }
            }

            if (UseAreaAvailable)
            {
                LinkedLandItem.TransactionOccurred += LinkedLandItem_TransactionOccurred;
            }

            ResourceRequestList = new List <ResourceRequest>
            {
                new ResourceRequest()
                {
                    Resource           = land,
                    AllowTransmutation = false,
                    Required           = UseAreaAvailable ? LinkedLandItem.AreaAvailable : AreaRequested,
                    ResourceType       = typeof(Land),
                    ResourceTypeName   = LandTypeNameToUse.Split('.').Last(),
                    ActivityModel      = this,
                    Category           = TransactionCategory,
                    FilterDetails      = null
                }
            };

            CheckResources(ResourceRequestList, Guid.NewGuid());
            gotLandRequested = TakeResources(ResourceRequestList, false);

            //Now the Land has been allocated we have an Area
            if (gotLandRequested)
            {
                //get the units of area for this run from the Land resource parent.
                unitsOfArea2Ha = Resources.FindResourceGroup <Land>().UnitsOfAreaToHaConversion;

                // locate Pasture Type resource
                LinkedNativeFoodType = Resources.FindResourceType <GrazeFoodStore, GrazeFoodStoreType>(this, FeedTypeName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop);

                //Assign the area actually got after taking it. It might be less than AreaRequested (if partial)
                Area = ResourceRequestList.FirstOrDefault().Provided;

                // ensure no other activity has set the area of this GrazeFoodStore
                LinkedNativeFoodType.Manager = this as IPastureManager;

                soilIndex = ((LandType)ResourceRequestList.FirstOrDefault().Resource).SoilType;

                if (!(LandConditionIndex is null))
                {
                    LinkedNativeFoodType.CurrentEcologicalIndicators.LandConditionIndex = LandConditionIndex.StartingValue;
                }

                if (!(GrassBasalArea is null))
                {
                    LinkedNativeFoodType.CurrentEcologicalIndicators.GrassBasalArea = GrassBasalArea.StartingValue;
                }

                LinkedNativeFoodType.CurrentEcologicalIndicators.StockingRate = StartingStockingRate;
                stockingRateSummed = StartingStockingRate;

                //Now we have a stocking rate and we have starting values for Land Condition and Grass Basal Area
                //get the starting pasture data list from Pasture reader
                if (filePasture != null & LinkedNativeFoodType != null)
                {
                    GetPastureDataList_TodayToNextEcolCalculation();

                    double firstMonthsGrowth = 0;
                    if (pastureDataList != null)
                    {
                        PastureDataType pasturedata = pastureDataList.Where(a => a.Year == clock.StartDate.Year && a.Month == clock.StartDate.Month).FirstOrDefault();
                        firstMonthsGrowth = pasturedata.Growth;
                    }

                    LinkedNativeFoodType.SetupStartingPasturePools(Area * unitsOfArea2Ha, firstMonthsGrowth);
                }
            }
        }