private bool CheckStarvationDispersal(ModelGrid gridForDispersal, uint latIndex, uint lonIndex, Cohort cohortToDisperse, int functionalGroup, int cohortNumber)
{
// A boolean to check whether a cohort has dispersed
bool CohortHasDispersed = false;
// Check for starvation driven dispersal
// What is the present body mass of the cohort?
// Note that at present we are just tracking starvation for adults
double IndividualBodyMass = cohortToDisperse.IndividualBodyMass;
double AdultMass = cohortToDisperse.AdultMass;
// Temporary variables to keep track of directions in which cohorts enter/exit cells during the multiple advection steps per time step
uint ExitDirection = new uint();
uint EntryDirection = new uint();
ExitDirection = 9999;
// Assume a linear relationship between probability of dispersal and body mass loss, up to _StarvationDispersalBodyMassThreshold
// at which point the cohort will try to disperse every time step
if (IndividualBodyMass < AdultMass)
{
double ProportionalPresentMass = IndividualBodyMass / AdultMass;
// If the body mass loss is greater than the starvation dispersal body mass threshold, then the cohort tries to disperse
if (ProportionalPresentMass < _StarvationDispersalBodyMassThreshold)
{
// Cohort tries to disperse
double[] DispersalArray = CalculateDispersalProbability(gridForDispersal, latIndex, lonIndex, CalculateDispersalSpeed(AdultMass));
double CohortDispersed = CheckForDispersal(DispersalArray[0]);
if (CohortDispersed > 0)
{
uint[] DestinationCell = CellToDisperseTo(gridForDispersal, latIndex, lonIndex, DispersalArray, CohortDispersed, DispersalArray[4], DispersalArray[5], ref ExitDirection, ref EntryDirection);
// Update the delta array of cells to disperse to, if the cohort moves
if (DestinationCell[0] < 999999)
{
// Update the delta array of cohorts
gridForDispersal.DeltaFunctionalGroupDispersalArray[latIndex, lonIndex].Add((uint)functionalGroup);
gridForDispersal.DeltaCohortNumberDispersalArray[latIndex, lonIndex].Add((uint)cohortNumber);
// Update the delta array of cells to disperse to
gridForDispersal.DeltaCellToDisperseToArray[latIndex, lonIndex].Add(DestinationCell);
// Update the delta array of exit and entry directions
gridForDispersal.DeltaCellExitDirection[latIndex, lonIndex].Add(ExitDirection);
gridForDispersal.DeltaCellEntryDirection[latIndex, lonIndex].Add(EntryDirection);
}
}
// Note that regardless of whether or not it succeeds, if a cohort tries to disperse, it is counted as having dispersed for
// the purposes of not then allowing it to disperse based on its density.
CohortHasDispersed = true;
}
// Otherwise, the cohort has a chance of trying to disperse proportional to its mass loss
else
{
// Cohort tries to disperse with a particular probability
// Draw a random number
if (((1.0 - ProportionalPresentMass) / (1.0 - _StarvationDispersalBodyMassThreshold)) > RandomNumberGenerator.GetUniform())
{
// Cohort tries to disperse
double[] DispersalArray = CalculateDispersalProbability(gridForDispersal, latIndex, lonIndex, CalculateDispersalSpeed(AdultMass));
double CohortDispersed = CheckForDispersal(DispersalArray[0]);
if (CohortDispersed > 0)
{
uint[] DestinationCell = CellToDisperseTo(gridForDispersal, latIndex, lonIndex, DispersalArray, CohortDispersed, DispersalArray[4], DispersalArray[5], ref ExitDirection, ref EntryDirection);
// Update the delta array of cells to disperse to, if the cohort moves
if (DestinationCell[0] < 999999)
{
// Update the delta array of cohorts
gridForDispersal.DeltaFunctionalGroupDispersalArray[latIndex, lonIndex].Add((uint)functionalGroup);
gridForDispersal.DeltaCohortNumberDispersalArray[latIndex, lonIndex].Add((uint)cohortNumber);
// Update the delta array of cells to disperse to
gridForDispersal.DeltaCellToDisperseToArray[latIndex, lonIndex].Add(DestinationCell);
// Update the delta array of exit and entry directions
gridForDispersal.DeltaCellExitDirection[latIndex, lonIndex].Add(ExitDirection);
gridForDispersal.DeltaCellEntryDirection[latIndex, lonIndex].Add(EntryDirection);
}
}
CohortHasDispersed = true;
}
}
}
return CohortHasDispersed;
}