/// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        public new void Remove(ResourceRequest request)
        {
            // handles grazing by breed from this pasture pools based on breed pool limits

            if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(RuminantActivityGrazePastureHerd))
            {
                RuminantActivityGrazePastureHerd thisBreed = request.AdditionalDetails as RuminantActivityGrazePastureHerd;

                // take from pools as specified for the breed
                double amountRequired      = request.Required;
                bool   secondTakeFromPools = thisBreed.RuminantTypeModel.StrictFeedingLimits;
                thisBreed.DMD = 0;
                thisBreed.N   = 0;
                int index = 0;
                while (amountRequired > 0)
                {
                    // limiter obtained from breed feed limits or unlimited if second take of pools
                    double limiter = 1.0;
                    if (!secondTakeFromPools)
                    {
                        limiter = thisBreed.PoolFeedLimits[index].Limit;
                    }

                    double amountToRemove = Math.Min(this.Pools[index].Amount, amountRequired * limiter);
                    // update DMD and N based on pool utilised
                    thisBreed.DMD  += this.Pools[index].DMD * amountToRemove;
                    thisBreed.N    += this.Pools[index].Nitrogen * amountToRemove;
                    amountRequired -= amountToRemove;

                    // remove resource from pool
                    this.Pools[index].Remove(amountToRemove, thisBreed, "Graze");

                    index++;
                    if (index >= this.Pools.Count)
                    {
                        // if we've already given second chance to get food so finish without full satisfying individual
                        // or strict feeding limits are enforced
                        if (secondTakeFromPools)
                        {
                            break;
                        }
                        // if not strict limits allow a second request for food from previously limited pools.
                        secondTakeFromPools = true;
                        index = 0;
                    }
                }

                request.Provided = request.Required - amountRequired;

                // adjust DMD and N of biomass consumed
                thisBreed.DMD /= request.Provided;
                thisBreed.N   /= request.Provided;

                //if graze activity
                biomassConsumed += request.Provided;

                // report
                ResourceTransaction details = new ResourceTransaction();
                details.ResourceType = this.Name;
                details.Loss         = request.Provided;
                details.Activity     = request.ActivityModel.Name;
                details.ActivityType = request.ActivityModel.GetType().Name;
                details.Reason       = request.Reason;
                LastTransaction      = details;
                TransactionEventArgs te = new TransactionEventArgs()
                {
                    Transaction = details
                };
                OnTransactionOccurred(te);
            }
            else if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(PastureActivityCutAndCarry))
            {
                // take from pools by cut and carry
                double amountRequired         = request.Required;
                double amountCollected        = 0;
                double dryMatterDigestibility = 0;
                double nitrogen = 0;

                // take proportionally from all pools.
                double useproportion = Math.Min(1.0, amountRequired / Pools.Sum(a => a.Amount));
                // if less than pools then take required as proportion of pools
                foreach (GrazeFoodStorePool pool in Pools)
                {
                    double amountToRemove = pool.Amount * useproportion;
                    amountCollected        += amountToRemove;
                    dryMatterDigestibility += pool.DMD * amountToRemove;
                    nitrogen += pool.Nitrogen * amountToRemove;
                    pool.Remove(amountToRemove, this, "Cut and Carry");
                }
                request.Provided = amountCollected;

                // adjust DMD and N of biomass consumed
                dryMatterDigestibility /= request.Provided;
                nitrogen /= request.Provided;

                // report
                ResourceTransaction details = new ResourceTransaction();
                details.ResourceType = this.Name;
                details.Gain         = request.Provided * -1;
                details.Activity     = request.ActivityModel.Name;
                details.ActivityType = request.ActivityModel.GetType().Name;
                details.Reason       = request.Reason;
                LastTransaction      = details;
                TransactionEventArgs te = new TransactionEventArgs()
                {
                    Transaction = details
                };
                OnTransactionOccurred(te);
            }
            else
            {
                // Need to add new section here to allow non grazing activity to remove resources from pasture.
                throw new Exception("Removing resources from native food store can only be performed by a grazing and cut and carry activities at this stage");
            }
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        public new void Remove(ResourceRequest request)
        {
            // handles grazing by breed from this pasture pools based on breed pool limits

            if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(RuminantActivityGrazePastureHerd))
            {
                RuminantActivityGrazePastureHerd thisBreed = request.AdditionalDetails as RuminantActivityGrazePastureHerd;

                // take from pools as specified for the breed
                double amountRequired = request.Required;
                thisBreed.DMD = 0;
                thisBreed.N   = 0;

                // first take from pools
                foreach (GrazeBreedPoolLimit pool in thisBreed.PoolFeedLimits)
                {
                    // take min of amount in pool, intake*limiter, remaining intake needed
                    double amountToRemove = Math.Min(request.Required * pool.Limit, Math.Min(pool.Pool.Amount, amountRequired));
                    // update DMD and N based on pool utilised
                    thisBreed.DMD += pool.Pool.DMD * amountToRemove;
                    thisBreed.N   += pool.Pool.Nitrogen * amountToRemove;

                    amountRequired -= amountToRemove;

                    // remove resource from pool
                    pool.Pool.Remove(amountToRemove, thisBreed, "Graze");

                    if (amountRequired <= 0)
                    {
                        break;
                    }
                }

                // if forage still limiting and second take allowed (enforce strict limits is false)
                if (amountRequired > 0 & !thisBreed.RuminantTypeModel.StrictFeedingLimits)
                {
                    // allow second take for the limited pools
                    double forage = thisBreed.PoolFeedLimits.Sum(a => a.Pool.Amount);

                    // this will only be the previously limited pools
                    double amountTakenDuringSecondTake = 0;
                    foreach (GrazeBreedPoolLimit pool in thisBreed.PoolFeedLimits.Where(a => a.Limit < 1))
                    {
                        //if still not enough take all
                        double amountToRemove = 0;
                        if (amountRequired >= forage)
                        {
                            // take as a proportion of the pool to total forage remaining
                            amountToRemove = pool.Pool.Amount / forage * amountRequired;
                        }
                        else
                        {
                            amountToRemove = pool.Pool.Amount;
                        }
                        // update DMD and N based on pool utilised
                        thisBreed.DMD += pool.Pool.DMD * amountToRemove;
                        thisBreed.N   += pool.Pool.Nitrogen * amountToRemove;
                        amountTakenDuringSecondTake += amountToRemove;
                        // remove resource from pool
                        pool.Pool.Remove(amountToRemove, thisBreed, "Graze");
                    }
                    amountRequired -= amountTakenDuringSecondTake;
                }

                request.Provided = request.Required - amountRequired;

                // adjust DMD and N of biomass consumed
                thisBreed.DMD /= request.Provided;
                thisBreed.N   /= request.Provided;

                //if graze activity
                biomassConsumed += request.Provided;

                // report
                ResourceTransaction details = new ResourceTransaction
                {
                    ResourceType      = this,
                    Style             = TransactionStyle.Loss,
                    Amount            = request.Provided,
                    Activity          = request.ActivityModel,
                    Category          = request.Category,
                    RelatesToResource = request.RelatesToResource
                };
                LastTransaction = details;
                TransactionEventArgs te = new TransactionEventArgs()
                {
                    Transaction = details
                };
                OnTransactionOccurred(te);
            }
            else if (request.AdditionalDetails != null && request.AdditionalDetails.GetType() == typeof(PastureActivityCutAndCarry))
            {
                // take from pools by cut and carry
                double amountRequired         = request.Required;
                double amountCollected        = 0;
                double dryMatterDigestibility = 0;
                double nitrogen = 0;

                // take proportionally from all pools.
                double useproportion = Math.Min(1.0, amountRequired / Pools.Sum(a => a.Amount));
                // if less than pools then take required as proportion of pools
                foreach (GrazeFoodStorePool pool in Pools)
                {
                    double amountToRemove = pool.Amount * useproportion;
                    amountCollected        += amountToRemove;
                    dryMatterDigestibility += pool.DMD * amountToRemove;
                    nitrogen += pool.Nitrogen * amountToRemove;
                    pool.Remove(amountToRemove, this, "Cut and Carry");
                }
                request.Provided = amountCollected;

                // adjust DMD and N of biomass consumed
                dryMatterDigestibility /= request.Provided;
                nitrogen /= request.Provided;

                // report
                ResourceTransaction details = new ResourceTransaction
                {
                    ResourceType      = this,
                    Style             = TransactionStyle.Loss,
                    Amount            = request.Provided,
                    Activity          = request.ActivityModel,
                    Category          = request.Category,
                    RelatesToResource = request.RelatesToResource
                };
                LastTransaction = details;
                TransactionEventArgs te = new TransactionEventArgs()
                {
                    Transaction = details
                };
                OnTransactionOccurred(te);
            }
            else
            {
                // Need to add new section here to allow non grazing activity to remove resources from pasture.
                throw new Exception("Removing resources from native food store can only be performed by a grazing and cut and carry activities at this stage");
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="Request"></param>
        public void Remove(ResourceRequest Request)
        {
            // handles grazing by breed from this pasture pools based on breed pool limits

            if (Request.AdditionalDetails != null && Request.AdditionalDetails.GetType() == typeof(RuminantActivityGrazePastureHerd))
            {
                RuminantActivityGrazePastureHerd thisBreed = Request.AdditionalDetails as RuminantActivityGrazePastureHerd;

                // take from pools as specified for the breed
                double amountRequired      = Request.Required;
                bool   secondTakeFromPools = thisBreed.RuminantTypeModel.StrictFeedingLimits;
                thisBreed.DMD = 0;
                thisBreed.N   = 0;
                int index = 0;
                while (amountRequired > 0)
                {
                    // limiter obtained from breed feed limits or unlimited if second take of pools
                    double limiter = 1.0;
                    if (!secondTakeFromPools)
                    {
                        limiter = thisBreed.PoolFeedLimits[index].Limit;
                    }

                    double amountToRemove = Math.Min(this.Pools[index].Amount, amountRequired * limiter);
                    // update DMD and N based on pool utilised
                    thisBreed.DMD  += this.Pools[index].DMD * amountToRemove;
                    thisBreed.N    += this.Pools[index].Nitrogen * amountToRemove;
                    amountRequired -= amountToRemove;

                    // remove resource from pool
                    this.Pools[index].Remove(amountToRemove, "Graze", thisBreed.Name);

                    index++;
                    if (index >= this.Pools.Count)
                    {
                        // if we've already given second chance to get food so finish without full satisfying individual
                        // or strict feeding limits are enforced
                        if (secondTakeFromPools)
                        {
                            break;
                        }
                        // if not strict limits allow a second request for food from previously limited pools.
                        secondTakeFromPools = true;
                        index = 0;
                    }
                }

                Request.Provided = Request.Required - amountRequired;

                // adjust DMD and N of biomass consumed
                thisBreed.DMD /= Request.Provided;
                thisBreed.N   /= Request.Provided;

                //if graze activity
                biomassConsumed += Request.Provided;

                // report
                ResourceTransaction details = new ResourceTransaction();
                details.ResourceType = this.Name;
                details.Debit        = Request.Provided * -1;
                details.Activity     = Request.ActivityModel.Name;
                details.Reason       = Request.Reason;
                LastTransaction      = details;
                TransactionEventArgs te = new TransactionEventArgs()
                {
                    Transaction = details
                };
                OnTransactionOccurred(te);
            }
            else
            {
                // Need to add new section here to allow non grazing activity to remove resources from pasture.
                throw new Exception("Removing resources from native food store can only be performed by a grazing activity at this stage");
            }
        }