private void OnCLEMAnimalStock(object sender, EventArgs e) { // this event happens after management has marked individuals for purchase or sale. if (Clock.Today.Month == AssessmentMonth) { // Get ENSO forcase for current time ENSOState forecastEnsoState = GetENSOMeasure(); // calculate dry season pasture available for each managed paddock holding stock RuminantHerd ruminantHerd = Resources.RuminantHerd(); foreach (var newgroup in ruminantHerd.Herd.Where(a => a.Location != "").GroupBy(a => a.Location)) { // total adult equivalents of all breeds on pasture for utilisation double totalAE = newgroup.Sum(a => a.AdultEquivalent); // determine AE marked for sale and purchase of managed herd double markedForSaleAE = newgroup.Where(a => a.ReadyForSale && a.HerdName == HerdName).Sum(a => a.AdultEquivalent); double purchaseAE = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == newgroup.Key && a.HerdName == HerdName).Sum(a => a.AdultEquivalent); double herdChange = 1.0; switch (forecastEnsoState) { case ENSOState.Neutral: break; case ENSOState.ElNino: GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; double kgha = pasture.TonnesPerHectare * 1000; //NOTE: ensure calculation method in relationship is fixed values herdChange = this.PastureToStockingChangeElNino.SolveY(kgha); break; case ENSOState.LaNina: pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; kgha = pasture.TonnesPerHectare * 1000; herdChange = this.PastureToStockingChangeLaNina.SolveY(kgha); break; default: break; } if (herdChange > 1.0) { double toBuyAE = Math.Max(0, (totalAE * herdChange) - purchaseAE); HandleRestocking(toBuyAE, newgroup.Key, newgroup.FirstOrDefault()); } else if (herdChange < 1.0) { double toSellAE = Math.Max(0, (totalAE * (1 - herdChange)) - markedForSaleAE); HandleDestocking(toSellAE, newgroup.Key); } } } }
private void OnCLEMAnimalStock(object sender, EventArgs e) { // this event happens after management has marked individuals for purchase or sale. if (Clock.Today.Month == AssessmentMonth) { // Get ENSO forcase for current time ENSOState ForecastEnsoState = GetENSOMeasure(); // calculate dry season pasture available for each managed paddock holding stock RuminantHerd ruminantHerd = Resources.RuminantHerd(); foreach (var newgroup in ruminantHerd.Herd.Where(a => a.Location != "").GroupBy(a => a.Location)) { // total adult equivalents of all breeds on pasture for utilisation double AETotal = newgroup.Sum(a => a.AdultEquivalent); // determine AE marked for sale and purchase of managed herd double AEmarkedForSale = newgroup.Where(a => a.ReadyForSale & a.HerdName == HerdName).Sum(a => a.AdultEquivalent); double AEPurchase = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == newgroup.Key & a.HerdName == HerdName).Sum(a => a.AdultEquivalent); double herdChange = 1.0; switch (ForecastEnsoState) { case ENSOState.Neutral: break; case ENSOState.ElNino: GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; double kgha = pasture.TonnesPerHectare * 1000; herdChange = this.PastureToStockingChangeElNino.SolveY(kgha, false); break; case ENSOState.LaNina: pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; kgha = pasture.TonnesPerHectare * 1000; herdChange = this.PastureToStockingChangeLaNina.SolveY(kgha, false); break; default: break; } if (herdChange > 1.0) { double AEtoBuy = Math.Max(0, (AETotal * herdChange) - AEPurchase); HandleRestocking(AEtoBuy, newgroup.Key, newgroup.FirstOrDefault()); } else if (herdChange < 1.0) { double AEtoSell = Math.Max(0, (AETotal * (1 - herdChange)) - AEmarkedForSale); HandleDestocking(AEtoSell, newgroup.Key); } //switch (ForecastEnsoState) //{ // case ENSOState.Neutral: // break; // case ENSOState.LaNina: // double AEtoBuy = 0; // GrazeFoodStoreType pasture = Resources.GetResourceItem(typeof(GrazeFoodStoreType), newgroup.Key, out available) as GrazeFoodStoreType; // double kgha = pasture.TonnesPerHectare * 1000; // if (kgha > 3000) // { // AEtoBuy = AETotal * 0.2; //Buy 20% of Total Animal Equivalents // } // else if (kgha < 1000) // { // AEtoBuy = 0; //Don't buy any nore // } // else // { // AEtoBuy = AETotal * 0.1; //Buy 10 % of Total Animal Equivalents // } // // adjust for the AE already marked for purchase if any // AEtoBuy = Math.Max(0, AEtoBuy - AEPurchase); // HandleRestocking(AEtoBuy, newgroup.Key, newgroup.FirstOrDefault()); // break; // case ENSOState.ElNino: // pasture = Resources.GetResourceItem(typeof(GrazeFoodStoreType), newgroup.Key, out available) as GrazeFoodStoreType; // kgha = pasture.TonnesPerHectare * 1000; // if (kgha > 3000) // { // ShortfallAE = AETotal * 0.1; //Sell 10% of Total Animal Equivalents // } // else if (kgha < 1000) // { // ShortfallAE = AETotal * 0.3; //Sell 30% of Total Animal Equivalents // } // else // { // ShortfallAE = AETotal * 0.2; //Sell 20 % of Total Animal Equivalents // } // // Adjust for AE already flagged for sale if any // ShortfallAE = Math.Max(0, ShortfallAE - AEmarkedForSale); // HandleDestocking(ShortfallAE, newgroup.Key); // break; // default: // break; //} } } }
private void OnCLEMAnimalStock(object sender, EventArgs e) { AeToDestock = 0; AeDestocked = 0; AeToRestock = 0; AeRestocked = 0; // this event happens after management has marked individuals for purchase or sale. if (this.TimingOK) { // Get ENSO forcase for current time ENSOState forecastEnsoState = GetENSOMeasure(); this.Status = ActivityStatus.NotNeeded; // calculate dry season pasture available for each managed paddock holding stock RuminantHerd ruminantHerd = Resources.RuminantHerd(); foreach (var newgroup in ruminantHerd.Herd.Where(a => a.Location != "").GroupBy(a => a.Location)) { double aELocationNeeded = 0; // total adult equivalents of all breeds on pasture for utilisation double totalAE = newgroup.Sum(a => a.AdultEquivalent); // determine AE marked for sale and purchase of managed herd double markedForSaleAE = newgroup.Where(a => a.ReadyForSale).Sum(a => a.AdultEquivalent); double purchaseAE = ruminantHerd.PurchaseIndividuals.Where(a => a.Location == newgroup.Key).Sum(a => a.AdultEquivalent); double herdChange = 1.0; bool relationshipFound = false; switch (forecastEnsoState) { case ENSOState.Neutral: break; case ENSOState.ElNino: if (!(pastureToStockingChangeElNino is null)) { GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; double kgha = pasture.TonnesPerHectare * 1000; herdChange = pastureToStockingChangeElNino.SolveY(kgha); relationshipFound = true; } break; case ENSOState.LaNina: if (!(pastureToStockingChangeLaNina is null)) { GrazeFoodStoreType pasture = Resources.GetResourceItem(this, typeof(GrazeFoodStoreType), newgroup.Key, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as GrazeFoodStoreType; double kgha = pasture.TonnesPerHectare * 1000; herdChange = pastureToStockingChangeLaNina.SolveY(kgha); relationshipFound = true; } break; default: break; } if (!relationshipFound) { string warn = $"No pasture biomass to herd change proportion [Relationship] provided for {((forecastEnsoState== ENSOState.ElNino)? "El Niño":"La Niña")} phase in [a={this.Name}]\r\nNo stock management will be performed in this phase."; this.Status = ActivityStatus.Warning; if (!Warnings.Exists(warn)) { Summary.WriteWarning(this, warn); Warnings.Add(warn); } } if (herdChange > 1.0) { aELocationNeeded = Math.Max(0, (totalAE * herdChange) - purchaseAE); AeToRestock += aELocationNeeded; double notHandled = HandleRestocking(aELocationNeeded, newgroup.Key, newgroup.FirstOrDefault()); AeRestocked += (aELocationNeeded - notHandled); } else if (herdChange < 1.0) { aELocationNeeded = Math.Max(0, (totalAE * (1 - herdChange)) - markedForSaleAE); AeToDestock += aELocationNeeded; double notHandled = HandleDestocking(AeToDestock, newgroup.Key); AeDestocked += (aELocationNeeded - notHandled); } } if (this.Status != ActivityStatus.Warning & AeToDestock + AeToRestock > 0) { if (Math.Max(0, AeToRestock - AeRestocked) + Math.Max(0, AeToDestock - AeDestocked) == 0) { this.Status = ActivityStatus.Success; } else { this.Status = ActivityStatus.Partial; } } } }