/// <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"); } }
/// <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"); } }