//--------------------------------------------------------------------- private List<Site> GetNeighbors(Site site, int windDirection) { List<Site> neighbors = new List<Site>(5); foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if (neighbor != null) neighbors.Add(neighbor); } int vertical=0; int horizontal=0; if(windDirection==1) { //wind is from south vertical = -2; horizontal = 0; } if(windDirection==2) { //wind is from north vertical = 2; horizontal = 0; } if(windDirection==3) { //wind is from east vertical = 0; horizontal = -2; } if(windDirection==4) { //wind is from west vertical = 0; horizontal = 2; } RelativeLocation relativeLoc5 = new RelativeLocation(vertical, horizontal); Site neighbor5 = site.GetNeighbor(relativeLoc5); if (neighbor5 != null) neighbors.Add(neighbor5); return neighbors; }
//--------------------------------------------------------------------- private List<Site> GetNeighbors(Site site, int windDirection, double windSpeed) { if(windDirection > 7) windDirection = 7; double[] windProbs = { (((4.0 - windSpeed)/8.0) * (1+windSpeed)), //Primary direction (((4.0 - windSpeed)/8.0) * (1+windSpeed)), (((4.0 - windSpeed)/8.0)), (((4.0 - windSpeed)/8.0) * (1-windSpeed)), (((4.0 - windSpeed)/8.0) * (1-windSpeed)), //Opposite of primary direction (((4.0 - windSpeed)/8.0) * (1-windSpeed)), (((4.0 - windSpeed)/8.0)), (((4.0 - windSpeed)/8.0) * (1+windSpeed)), }; double windProb = 0.0; int index = 0; int success = 0; List<Site> neighbors = new List<Site>(9); foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if(index + windDirection > 7) windProb = windProbs[index + windDirection - 8]; else windProb = windProbs[index + windDirection]; //System.Console.WriteLine("WindProb={0:0.00}, windSpeed={1:0.00}, neighbor={2}.", windProb, windSpeed, index+1); if (neighbor != null && Random.GenerateUniform() < windProb) { neighbors.Add(neighbor); success++; } index++; } logger.Debug(string.Format("Successfully added {0} neighbors.", success)); //Next, add the 9th neighbor, a neighbor one cell beyond the //8 nearest neighbors. //array index 0 = north; 1 = northeast, 2 = east,...,8 = northwest int[] vertical ={2,2,0,-2,-2,-2,0,2}; int[] horizontal={0,2,2,2,0,-2,-2,-2}; RelativeLocation relativeLoc9 = new RelativeLocation(vertical[windDirection], horizontal[windDirection]); Site neighbor9 = site.GetNeighbor(relativeLoc9); if (neighbor9 != null && Random.GenerateUniform() < windSpeed) neighbors.Add(neighbor9); return neighbors; }
//--------------------------------------------------------------------- // This method replaces the delegate method. It is called every year when // ACT_ANPP is calculated, for each cohort. Therefore, this method is operating at // an ANNUAL time step and separate from the normal extension time step. public static double DefoliateCohort(Biomass.ICohort cohort, Site site, int siteBiomass) { //UI.WriteLine(" Calculating insect defoliation..."); int sppIndex = cohort.Species.Index; double totalDefoliation = 0.0; foreach(IInsect insect in manyInsect) { if(!insect.ActiveOutbreak) continue; double defoliation = 0.0; double weightedDefoliation = 0.0; int suscIndex = insect.SppTable[sppIndex].Susceptibility - 1; if (suscIndex < 0) suscIndex = 0; // Get the Neighborhood GrowthReduction Density double meanNeighborhoodDefoliation = 0.0; int neighborCnt = 0; // If it is the first year, the neighborhood growth reduction // will have been initialized in Outbreak.InitializeDefoliationPatches if(insect.NeighborhoodDefoliation[site] > 0) { //UI.WriteLine(" First Year of Defoliation: Using initial patch defo={0:0.00}.", SiteVars.NeighborhoodDefoliation[site]); meanNeighborhoodDefoliation = insect.NeighborhoodDefoliation[site]; } // If not the first year, calculate mean neighborhood defoliation based on the // previous year. else { double sumNeighborhoodDefoliation = 0.0; //UI.WriteLine("Look at the Neighbors... "); foreach (RelativeLocation relativeLoc in insect.Neighbors) { Site neighbor = site.GetNeighbor(relativeLoc); if (neighbor != null && neighbor.IsActive) { neighborCnt++; // The previous year... //if(SiteVars.DefoliationByYear[neighbor].ContainsKey(Model.Core.CurrentTime - 1)) // sumNeighborhoodDefoliation += SiteVars.DefoliationByYear[neighbor][Model.Core.CurrentTime - 1]; sumNeighborhoodDefoliation += insect.LastYearDefoliation[neighbor]; } } if(neighborCnt > 0.0) meanNeighborhoodDefoliation = sumNeighborhoodDefoliation / (double) neighborCnt; } //endif if(meanNeighborhoodDefoliation > 1.0 || meanNeighborhoodDefoliation < 0) { UI.WriteLine("MeanNeighborhoodDefoliation={0}; NeighborCnt={1}.", meanNeighborhoodDefoliation, neighborCnt); throw new ApplicationException("Error: Mean Neighborhood GrowthReduction is not between 1.0 and 0.0"); } // First assume that there are no neighbors whatsoever: DistributionType dist = insect.SusceptibleTable[suscIndex].Distribution_0.Name; double value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1; double value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2; if(meanNeighborhoodDefoliation <= 1.0 && meanNeighborhoodDefoliation >= 0.8) { dist = insect.SusceptibleTable[suscIndex].Distribution_80.Name; value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1; value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2; } else if(meanNeighborhoodDefoliation < 0.8 && meanNeighborhoodDefoliation >= 0.6) { dist = insect.SusceptibleTable[suscIndex].Distribution_60.Name; value1 = insect.SusceptibleTable[suscIndex].Distribution_60.Value1; value2 = insect.SusceptibleTable[suscIndex].Distribution_60.Value2; } else if(meanNeighborhoodDefoliation < 0.6 && meanNeighborhoodDefoliation >= 0.4) { dist = insect.SusceptibleTable[suscIndex].Distribution_40.Name; value1 = insect.SusceptibleTable[suscIndex].Distribution_40.Value1; value2 = insect.SusceptibleTable[suscIndex].Distribution_40.Value2; } else if(meanNeighborhoodDefoliation < 0.4 && meanNeighborhoodDefoliation >= 0.2) { dist = insect.SusceptibleTable[suscIndex].Distribution_20.Name; value1 = insect.SusceptibleTable[suscIndex].Distribution_20.Value1; value2 = insect.SusceptibleTable[suscIndex].Distribution_20.Value2; } else if(meanNeighborhoodDefoliation < 0.2 && meanNeighborhoodDefoliation >= 0.0) { dist = insect.SusceptibleTable[suscIndex].Distribution_0.Name; value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1; value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2; } // Next, ensure that all cohorts of the same susceptibility class // receive the same level of defoliation. if(insect.HostDefoliationByYear[site].ContainsKey(Model.Core.CurrentTime)) { if(insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] <= 0.00000000) { defoliation = Distribution.GenerateRandomNum(dist, value1, value2); insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] = defoliation; } else defoliation = insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex]; } else { insect.HostDefoliationByYear[site].Add(Model.Core.CurrentTime, new Double[3]{0.0, 0.0, 0.0}); defoliation = Distribution.GenerateRandomNum(dist, value1, value2); insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] = defoliation; } // Alternatively, allow defoliation to vary even among cohorts and species with // the same susceptibility. //defoliation = Distribution.GenerateRandomNum(dist, value1, value2); if(defoliation > 1.0 || defoliation < 0) { UI.WriteLine("DEFOLIATION TOO BIG or SMALL: {0}, {1}, {2}, {3}.", dist, value1, value2, defoliation); throw new ApplicationException("Error: New defoliation is not between 1.0 and 0.0"); } //UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, defoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex -1), defoliation); // For first insect in a given year, actual defoliation equals the potential defoliation drawn from insect distributions. if (totalDefoliation == 0.0) { weightedDefoliation = (defoliation * ((double)cohort.Biomass / (double)siteBiomass)); //UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, cohortDefoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex+1), cohortDefoliation); } // For second insect in a given year, actual defoliation can only be as high as the amount of canopy foliage left by first insect. // This change makes sure next year's neighborhoodDefoliation will reflect actual defoliation, rather than "potential" defoliation. // It should also ensure that the sum of defoliation maps for all insects adds up to 1 for a given year. else { weightedDefoliation = (Math.Min((1 - totalDefoliation), defoliation) * ((double)cohort.Biomass / (double)siteBiomass)); } insect.ThisYearDefoliation[site] += weightedDefoliation; if (insect.ThisYearDefoliation[site] > 1.0) // Weighted defoliation cannot exceed 100% of site biomass. insect.ThisYearDefoliation[site] = 1.0; //Put in error statement to see if sum of weighted defoliation is ever over 1. if (insect.ThisYearDefoliation[site] > 1.0 || insect.ThisYearDefoliation[site] < 0) { UI.WriteLine("Site Weighted Defoliation = {0:0.000000}. Site R/C={1}/{2}. Last Weighted Defoliation = {3}.", insect.ThisYearDefoliation[site], site.Location.Row, site.Location.Column, weightedDefoliation); throw new ApplicationException("Error: Site Weighted Defoliation is not between 1.0 and 0.0"); } totalDefoliation += defoliation; // Is totalDefoliation getting used anywhere else? Or an orphan? } if(totalDefoliation > 1.0) // Cannot exceed 100% defoliation, comment out to see if it ever does. totalDefoliation = 1.0; if(totalDefoliation > 1.0 || totalDefoliation < 0) { UI.WriteLine("Cohort Total Defoliation = {0:0.00}. Site R/C={1}/{2}.", totalDefoliation, site.Location.Row, site.Location.Column); throw new ApplicationException("Error: Total Defoliation is not between 1.0 and 0.0"); } return totalDefoliation; }
//--------------------------------------------------------------------- private List<Site> GetNeighbors(Site site, int windDirection) { if(windDirection > 7) windDirection = 7; double[] windProbs = { (((4.0 - this.intensity)/8.0) * (1+this.intensity)), //Primary direction (((4.0 - this.intensity)/8.0) * (1+this.intensity)), (((4.0 - this.intensity)/8.0)), (((4.0 - this.intensity)/8.0) * (1-this.intensity)), (((4.0 - this.intensity)/8.0) * (1-this.intensity)), //Opposite of primary direction (((4.0 - this.intensity)/8.0) * (1-this.intensity)), (((4.0 - this.intensity)/8.0)), (((4.0 - this.intensity)/8.0) * (1+this.intensity)), }; double windProb = 0.0; int index = 0; List<Site> neighbors = new List<Site>(9); foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if(index + windDirection > 7) windProb = windProbs[index + windDirection - 8]; else windProb = windProbs[index + windDirection]; if (neighbor != null && Random.GenerateUniform() < windProb) neighbors.Add(neighbor); index++; } //Next, add the 9th neighbor, a neighbor one cell beyond the //8 nearest neighbors. //array index 0 = north; 1 = northeast, 2 = east,...,8 = northwest int[] vertical ={2,2,0,-2,-2,-2,0,2}; int[] horizontal={0,2,2,2,0,-2,-2,-2}; RelativeLocation relativeLoc9 = new RelativeLocation(vertical[windDirection], horizontal[windDirection]); Site neighbor9 = site.GetNeighbor(relativeLoc9); if (neighbor9 != null && Random.GenerateUniform() < this.intensity) neighbors.Add(neighbor9); return neighbors; }
//--------------------------------------------------------------------- private List<Site> GetNeighbors(Site site) { List<Site> neighbors = new List<Site>(4); foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if (neighbor != null) neighbors.Add(neighbor); } return neighbors; }
private static List<Site> Get8Neighbors(Site site) { List<Site> neighbors = new List<Site>(); RelativeLocation[] neighborhood = new RelativeLocation[] { new RelativeLocation(-1, 0), // north new RelativeLocation(-1, 1), // northeast new RelativeLocation( 0, 1), // east new RelativeLocation( 1, 1), // southeast new RelativeLocation( 1, 0), // south new RelativeLocation( 1, -1), // southwest new RelativeLocation( 0, -1), // west new RelativeLocation(-1, -1), // northwest }; foreach (RelativeLocation relativeLoc in neighborhood) { Site neighbor = site.GetNeighbor(relativeLoc); if(neighbor != null && neighbor.IsActive) neighbors.Add(neighbor); } Landis.Util.Random.Shuffle(neighbors); return neighbors; }