private void Spread(int currentTime)
{
int windDirection = (int)(PlugIn.ModelCore.GenerateUniform() * 8);
double windSpeed = PlugIn.ModelCore.GenerateUniform();
int[] size = new int[FireRegions.Dataset.Count]; // in # of sites
int totalSitesInEvent = 0;
long totalSiteSeverities = 0;
int maxFireRegionSize = 0;
int siteCohortsKilled = 0;
IFireRegion ecoregion = SiteVars.FireRegion[initiationSite];
int ecoIndex = ecoregion.Index;
size[ecoIndex] = ComputeSize(ecoregion);
if (size[ecoIndex] > maxFireRegionSize)
maxFireRegionSize = size[ecoIndex];
//Create a queue of neighboring sites to which the fire will spread:
Queue<Site> sitesToConsider = new Queue<Site>();
sitesToConsider.Enqueue(initiationSite);
//Fire size cannot be larger than the size calculated for each ecoregion.
//Fire size cannot be larger than the largest size for any ecoregion.
while (sitesToConsider.Count > 0 &&
this.sitesInEvent[ecoIndex] < size[ecoIndex] &&
totalSitesInEvent < maxFireRegionSize)
{
this.numSiteChecked++;
Site site = sitesToConsider.Dequeue();
currentSite = (ActiveSite)site; //site as ActiveSite;
ecoregion = SiteVars.FireRegion[site];
if (ecoregion.Index != ecoIndex)
{
ecoIndex = ecoregion.Index;
if (size[ecoIndex] < 1)
{
size[ecoIndex] = ComputeSize(ecoregion);
if (size[ecoIndex] > maxFireRegionSize)
maxFireRegionSize = size[ecoIndex];
}
}
SiteVars.Event[site] = this;
if (currentSite != null)
siteSeverity = CalcSeverity(currentSite, currentTime);
else
siteSeverity = 0;
if (siteSeverity > 0)
{
this.sitesInEvent[ecoIndex]++;
totalSitesInEvent++;
SiteVars.Severity[currentSite] = siteSeverity;
SiteVars.TimeOfLastFire[currentSite] = currentTime;
totalSiteSeverities += siteSeverity;
SiteVars.Disturbed[currentSite] = true;
siteCohortsKilled = KillSiteCohorts(currentSite);
if (siteCohortsKilled > 0)
{
totalSitesDamaged++;
}
//Next, add site's neighbors in random order to the list of
//sites to consider. The neighbors cannot be part of
//any other Fire event in the current timestep, and
//cannot already be on the list.
//Fire can burn into neighbors only if the
//spread probability is exceeded.
List<Site> neighbors = GetNeighbors(site, windDirection, windSpeed);
if (neighbors.Count > 0)
{
neighbors = PlugIn.ModelCore.shuffle(neighbors);
foreach (Site neighbor in neighbors)
{
if (!neighbor.IsActive)
continue;
if (SiteVars.Event[neighbor] != null)
continue;
if (sitesToConsider.Contains(neighbor))
continue;
if (PlugIn.ModelCore.GenerateUniform() <= ComputeFireInitSpreadProb((ActiveSite)neighbor, currentTime)) //(neighbor as ActiveSite, currentTime))
sitesToConsider.Enqueue(neighbor);
}
}
}
}
if (this.totalSitesDamaged == 0)
this.severity = 0;
else
{
this.severity = ((double) totalSiteSeverities) / totalSitesInEvent;
}
}