protected double[] CalculateDispersalProbability(ModelGrid madingleyGrid, uint latIndex, uint lonIndex, double dispersalSpeed)
{
double LatCellLength = madingleyGrid.CellHeightsKm[latIndex];
double LonCellLength = madingleyGrid.CellWidthsKm[latIndex];
// Pick a direction at random
double RandomDirection = RandomNumberGenerator.GetUniform() * 2 * Math.PI;
// Calculate the u and v components given the dispersal speed
double uSpeed = dispersalSpeed * Math.Cos(RandomDirection);
double vSpeed = dispersalSpeed * Math.Sin(RandomDirection);
// Check that the whole cell hasn't moved out (i.e. that dispersal speed is not greater than cell length).
// This could happen if dispersal speed was high enough; indicates a need to adjust the time step, or to slow dispersal
if ((uSpeed > LonCellLength) || (vSpeed > LatCellLength))
{
Debug.Fail("Dispersal probability should always be <= 1");
}
// Calculate the area of the grid cell that is now outside in the diagonal direction
double AreaOutsideBoth = Math.Abs(uSpeed * vSpeed);
// Calculate the area of the grid cell that is now outside in the u direction (not including the diagonal)
double AreaOutsideU = Math.Abs(uSpeed * LatCellLength) - AreaOutsideBoth;
// Calculate the proportion of the grid cell that is outside in the v direction (not including the diagonal
double AreaOutsideV = Math.Abs(vSpeed * LonCellLength) - AreaOutsideBoth;
// Get the cell area, in kilometres squared
double CellArea = madingleyGrid.GetCellEnvironment(latIndex, lonIndex)["Cell Area"][0];
// Convert areas to a probability
double DispersalProbability = (AreaOutsideU + AreaOutsideV + AreaOutsideBoth) / CellArea;
// Check that we don't have any issues
if (DispersalProbability > 1)
{
//Debug.Fail("Dispersal probability should always be <= 1");
DispersalProbability = 1.0;
}
double[] NewArray = { DispersalProbability, AreaOutsideU / CellArea, AreaOutsideV / CellArea, AreaOutsideBoth / CellArea, uSpeed, vSpeed };
return NewArray;
}